1 // Copyright 2022 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_bluetooth/vendor.h" 18 #include "pw_containers/vector.h" 19 #include "pw_function/function.h" 20 #include "pw_result/result.h" 21 #include "pw_span/span.h" 22 #include "pw_status/status.h" 23 24 namespace pw::bluetooth { 25 26 // The Controller class is a shim for communication between the Host and the 27 // Controller. 28 class Controller { 29 public: 30 // The lifetime of the span is only guaranteed for the lifetime of the 31 // function call. 32 using DataFunction = Function<void(span<const std::byte>)>; 33 34 // Bitmask of features the controller supports. 35 enum class FeaturesBits : uint32_t { 36 // Indicates support for transferring Synchronous Connection-Oriented link 37 // data over the HCI. Offloaded SCO links may still be supported even if HCI 38 // 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 documented 43 // at 44 // https://source.android.com/docs/core/connect/bluetooth/hci_requirements 45 kAndroidVendorExtensions = (1 << 2), 46 // Bits 3-31 reserved. 47 }; 48 49 enum class ScoCodingFormat : uint8_t { 50 kCvsd, 51 kMsbc, 52 }; 53 54 enum class ScoEncoding : uint8_t { 55 k8Bits, 56 k16Bits, 57 }; 58 59 enum class ScoSampleRate : uint8_t { 60 k8Khz, 61 k16Khz, 62 }; 63 64 // Closes the controller. `Close` should be called first to safely clean up 65 // state (which may be an asynchronous process). 66 virtual ~Controller() = default; 67 68 // Sets a function that will be called with HCI event packets received from 69 // the controller. This should be called before `Initialize` or else incoming 70 // packets will be dropped. The lifetime of data passed to `func` is only 71 // guaranteed for the lifetime of the function call. 72 virtual void SetEventFunction(DataFunction func) = 0; 73 74 // Sets a function that will be called with ACL data packets received from the 75 // controller. This should be called before `Initialize` or else incoming 76 // packets will be dropped. The lifetime of data passed to `func` is only 77 // guaranteed for the lifetime of the function call. 78 virtual void SetReceiveAclFunction(DataFunction func) = 0; 79 80 // Sets a function that will be called with SCO packets received from the 81 // controller. On Classic and Dual Mode stacks, this should be called before 82 // `Initialize` or else incoming packets will be dropped. The lifetime of data 83 // passed to `func` is only guaranteed for the lifetime of the function call. 84 virtual void SetReceiveScoFunction(DataFunction func) = 0; 85 86 // Initializes the controller interface and starts processing packets. 87 // `complete_callback` will be called with the result of initialization. 88 // `error_callback` will be called for fatal errors that occur after 89 // initialization. After a fatal error, this object is invalid. `Close` should 90 // be called to ensure a safe clean up. 91 virtual void Initialize(Callback<void(Status)> complete_callback, 92 Callback<void(Status)> error_callback) = 0; 93 94 // Closes the controller interface, resetting all state. `callback` will be 95 // called when closure is complete. After this method is called, this object 96 // should be considered invalid and no other methods should be called 97 // (including `Initialize`). 98 // `callback` will be called with: 99 // OK - the controller interface was successfully closed, or is already closed 100 // INTERNAL - the controller interface could not be closed 101 virtual void Close(Callback<void(Status)> callback) = 0; 102 103 // Sends an HCI command packet to the controller. 104 virtual void SendCommand(span<const std::byte> command) = 0; 105 106 // Sends an ACL data packet to the controller. 107 virtual void SendAclData(span<const std::byte> data) = 0; 108 109 // Sends a SCO data packet to the controller. 110 virtual void SendScoData(span<const std::byte> data) = 0; 111 112 // Configure the HCI for a SCO connection with the indicated parameters. 113 // `SetReceiveScoFunction` must be called before calling this method. 114 // `callback will be called with: 115 // OK - success, packets can be sent/received. 116 // UNIMPLEMENTED - the implementation/controller does not support SCO over HCI 117 // ALREADY_EXISTS - a SCO connection is already configured 118 // INTERNAL - an internal error occurred 119 virtual void ConfigureSco(ScoCodingFormat coding_format, 120 ScoEncoding encoding, 121 ScoSampleRate sample_rate, 122 Callback<void(Status)> callback) = 0; 123 124 // Releases the resources held by an active SCO connection. This should be 125 // called when a SCO connection is closed. `ConfigureSco` must be called 126 // before calling this method. 127 // `callback will be called with: 128 // OK - success, the SCO configuration was reset. 129 // UNIMPLEMENTED - the implementation/controller does not support SCO over HCI 130 // INTERNAL - an internal error occurred 131 virtual void ResetSco(Callback<void(Status)> callback) = 0; 132 133 // Calls `callback` with a bitmask of features supported by the controller. 134 virtual void GetFeatures(Callback<void(FeaturesBits)> callback) = 0; 135 136 // Encodes the vendor command indicated by `parameters`. 137 // `callback` will be called with the result of the encoding request. 138 // The lifetime of data passed to `callback` is only guaranteed for the 139 // lifetime of the function call. 140 virtual void EncodeVendorCommand( 141 VendorCommandParameters parameters, 142 Callback<void(Result<span<const std::byte>>)> callback) = 0; 143 }; 144 145 inline constexpr bool operator&(Controller::FeaturesBits left, 146 Controller::FeaturesBits right) { 147 return static_cast<bool>( 148 static_cast<std::underlying_type_t<Controller::FeaturesBits>>(left) & 149 static_cast<std::underlying_type_t<Controller::FeaturesBits>>(right)); 150 } 151 152 inline constexpr Controller::FeaturesBits operator|( 153 Controller::FeaturesBits left, Controller::FeaturesBits right) { 154 return static_cast<Controller::FeaturesBits>( 155 static_cast<std::underlying_type_t<Controller::FeaturesBits>>(left) | 156 static_cast<std::underlying_type_t<Controller::FeaturesBits>>(right)); 157 } 158 159 inline constexpr Controller::FeaturesBits& operator|=( 160 Controller::FeaturesBits& left, Controller::FeaturesBits right) { 161 return left = left | right; 162 } 163 164 } // namespace pw::bluetooth 165