xref: /aosp_15_r20/external/pigweed/pw_bluetooth/public/pw_bluetooth/controller2.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #pragma once
16 
17 #include "pw_async2/dispatcher.h"
18 #include "pw_async2/once_sender.h"
19 #include "pw_bluetooth/vendor.h"
20 #include "pw_channel/channel.h"
21 #include "pw_function/function.h"
22 #include "pw_result/result.h"
23 #include "pw_status/status.h"
24 
25 namespace pw::bluetooth {
26 
27 /// The Controller class is a shim for communication between the Host and the
28 /// Controller. Controller is a `pw::Channel` used to send and receive HCI
29 /// packets. The first byte of each datagram is a UART packet indicator
30 /// (`H4PacketType` Emboss enum).
31 class Controller2
32     : public pw::channel::Implement<pw::channel::ReliableDatagramReaderWriter> {
33  public:
34   /// Bitmask of features the controller supports.
35   enum class FeaturesBits : uint32_t {
36     /// Indicates support for transferring Synchronous Connection-Oriented (SCO)
37     /// link data over the HCI. Offloaded SCO links may still be supported even
38     /// if HCI SCO isn't.
39     kHciSco = (1 << 0),
40     /// Indicates support for the Set Acl Priority command.
41     kSetAclPriorityCommand = (1 << 1),
42     /// Indicates support for the `LE_Get_Vendor_Capabilities` command
43     /// documented at
44     /// [HCI
45     /// requirements](https://source.android.com/docs/core/connect/bluetooth/hci_requirements).
46     kAndroidVendorExtensions = (1 << 2),
47     /// Bits 3-31 reserved.
48   };
49 
50   enum class ScoCodingFormat : uint8_t {
51     kCvsd,
52     kMsbc,
53   };
54 
55   enum class ScoEncoding : uint8_t {
56     k8Bits,
57     k16Bits,
58   };
59 
60   enum class ScoSampleRate : uint8_t {
61     k8Khz,
62     k16Khz,
63   };
64 
65   /// Returns Ready when fatal errors occur after initialization. After a fatal
66   /// error, this object is invalid.
67   virtual async2::Poll<Status> PendError(async2::Context& cx) = 0;
68 
69   /// Initializes the controller interface and starts processing packets.
70   /// Asynchronously returns the result of initialization.
71   ///
72   /// On success, HCI packets may now be sent and received with this object.
73   virtual async2::OnceReceiver<Status> Initialize() = 0;
74 
75   /// Configure the HCI for a SCO connection with the indicated parameters.
76   /// @returns
77   /// * OK - success, packets can be sent/received.
78   /// * UNIMPLEMENTED - the implementation/controller does not support SCO over
79   ///     HCI
80   /// * ALREADY_EXISTS - a SCO connection is already configured
81   /// * INTERNAL - an internal error occurred
82   virtual async2::OnceReceiver<Status> ConfigureSco(
83       ScoCodingFormat coding_format,
84       ScoEncoding encoding,
85       ScoSampleRate sample_rate) = 0;
86 
87   /// Releases the resources held by an active SCO connection. This should be
88   /// called when a SCO connection is closed. No-op if no SCO connection is
89   /// configured.
90   /// @returns
91   /// * OK - success, the SCO configuration was reset.
92   /// * UNIMPLEMENTED - the implementation/controller does not support SCO over
93   /// * HCI INTERNAL - an internal error occurred
94   virtual async2::OnceReceiver<Status> ResetSco() = 0;
95 
96   /// @returns A bitmask of features supported by the controller.
97   virtual async2::OnceReceiver<FeaturesBits> GetFeatures() = 0;
98 
99   /// Encode the vendor-specific HCI command for a generic type of vendor
100   /// command, and return the encoded command in a buffer.
101   /// @param parameters Vendor command to encode.
102   /// @returns Returns the result of the encoding request. On success, contains
103   /// the command buffer.
104   virtual async2::OnceReceiver<Result<multibuf::MultiBuf>> EncodeVendorCommand(
105       VendorCommandParameters parameters) = 0;
106 };
107 
108 inline constexpr bool operator&(Controller2::FeaturesBits left,
109                                 Controller2::FeaturesBits right) {
110   return static_cast<bool>(
111       static_cast<std::underlying_type_t<Controller2::FeaturesBits>>(left) &
112       static_cast<std::underlying_type_t<Controller2::FeaturesBits>>(right));
113 }
114 
115 inline constexpr Controller2::FeaturesBits operator|(
116     Controller2::FeaturesBits left, Controller2::FeaturesBits right) {
117   return static_cast<Controller2::FeaturesBits>(
118       static_cast<std::underlying_type_t<Controller2::FeaturesBits>>(left) |
119       static_cast<std::underlying_type_t<Controller2::FeaturesBits>>(right));
120 }
121 
122 inline constexpr Controller2::FeaturesBits& operator|=(
123     Controller2::FeaturesBits& left, Controller2::FeaturesBits right) {
124   return left = left | right;
125 }
126 
127 }  // namespace pw::bluetooth
128