1 // Copyright 2023 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 #include <lib/fit/function.h> 17 #include <pw_async/dispatcher.h> 18 #include <pw_async/task.h> 19 20 #include <list> 21 #include <memory> 22 #include <optional> 23 #include <queue> 24 #include <unordered_map> 25 #include <unordered_set> 26 27 #include "pw_bluetooth/controller.h" 28 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" 29 #include "pw_bluetooth_sapphire/internal/host/common/identifier.h" 30 #include "pw_bluetooth_sapphire/internal/host/common/inspectable.h" 31 #include "pw_bluetooth_sapphire/internal/host/common/macros.h" 32 #include "pw_bluetooth_sapphire/internal/host/common/smart_task.h" 33 #include "pw_bluetooth_sapphire/internal/host/common/trace.h" 34 #include "pw_bluetooth_sapphire/internal/host/common/weak_self.h" 35 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h" 36 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" 37 #include "pw_bluetooth_sapphire/internal/host/transport/control_packets.h" 38 #include "pw_bluetooth_sapphire/internal/host/transport/emboss_control_packets.h" 39 40 namespace bt::hci { 41 42 // Represents the HCI Bluetooth command channel. Manages HCI command and event 43 // packet control flow. CommandChannel is expected to remain allocated as long 44 // as the host exists. On fatal errors, it is put into an inactive state where 45 // no packets are processed, but it may continue to be accessed by higher layers 46 // until shutdown completes. 47 class CommandChannel final { 48 public: 49 // Currently, two versions of the HCI packet infrastructure coexist. The old, 50 // packed-struct approach, which is being obsoleted in favor of a new 51 // Emboss-based packet infrastructure. Until all old instances of 52 // `CommandPacket` are replaced by `EmbossCommandPacket`, command packet 53 // transmission will support both versions. 54 // 55 // TODO(fxbug.dev/42167863): Finish migration away from 56 // std::unique_ptr<CommandPacket> and replace with EmbossCommandPacket. 57 using CommandPacketVariant = 58 std::variant<std::unique_ptr<CommandPacket>, EmbossCommandPacket>; 59 60 // Starts listening for HCI commands and starts handling commands and events. 61 explicit CommandChannel(pw::bluetooth::Controller* hci, 62 pw::async::Dispatcher& dispatcher); 63 64 ~CommandChannel(); 65 66 // Used to identify an individual HCI command<->event transaction. 67 using TransactionId = size_t; 68 69 enum class EventType { 70 kHciEvent, 71 kLEMetaEvent, 72 kVendorEvent, 73 }; 74 75 // Queues the given |command_packet| to be sent to the controller and returns 76 // a transaction ID. 77 // 78 // This call takes ownership of the contents of |command_packet|. 79 // |command_packet| MUST represent a valid HCI command packet. 80 // 81 // |callback| will be called with all events related to the transaction, 82 // unless the transaction is removed with RemoveQueuedCommand. If the command 83 // results in a CommandStatus event, it will be sent to this callback before 84 // the event with |complete_event_code| is sent. 85 // 86 // Synchronous transactions complete with a CommandComplete HCI event. This 87 // function is the only way to receive a CommandComplete event. 88 // 89 // Most asynchronous transactions return the CommandStatus event and another 90 // event to indicate completion, which should be indicated in 91 // |complete_event_code|. 92 // 93 // If |complete_event_code| is set to kCommandStatus, the transaction is 94 // considered complete when the CommandStatus event is received. 95 // 96 // |complete_event_code| cannot be a code that has been registered for events 97 // via AddEventHandler or its related methods. 98 // 99 // Returns a ID unique to the command transaction, or zero if the parameters 100 // are invalid. This ID will be supplied to |callback| in its |id| parameter 101 // to identify the transaction. 102 // 103 // NOTE: Commands queued are not guaranteed to be finished or sent in order, 104 // although commands with the same opcode will be sent in order, and commands 105 // with the same |complete_event_code| and |subevent_code| will be sent in 106 // order. If strict ordering of commands is required, use 107 // SequentialCommandRunner or callbacks for sequencing. 108 // 109 // See Bluetooth Core Spec v5.0, Volume 2, Part E, Section 4.4 "Command Flow 110 // Control" for more information about the HCI command flow control. 111 using CommandCallback = 112 fit::function<void(TransactionId id, const EventPacket& event)>; 113 using EmbossCommandCallback = fit::function<void( 114 TransactionId id, const EmbossEventPacket& event_packet)>; 115 using CommandCallbackVariant = 116 std::variant<CommandCallback, EmbossCommandCallback>; 117 TransactionId SendCommand(CommandPacketVariant command_packet, 118 CommandCallback callback, 119 hci_spec::EventCode complete_event_code = 120 hci_spec::kCommandCompleteEventCode); 121 122 // As SendCommand, but the transaction completes on the LE Meta Event. 123 // |le_meta_subevent_code| is a LE Meta Event subevent code as described in 124 // Core Spec v5.2, Vol 4, Part E, Sec 7.7.65. 125 // 126 // |le_meta_subevent_code| cannot be a code that has been registered for 127 // events via AddLEMetaEventHandler. 128 TransactionId SendLeAsyncCommand(CommandPacketVariant command_packet, 129 CommandCallback callback, 130 hci_spec::EventCode le_meta_subevent_code); 131 132 // As SendCommand, but will wait to run this command until there are no 133 // commands with with opcodes specified in |exclude| from executing. This is 134 // useful to prevent running different commands that cannot run concurrently 135 // (i.e. Inquiry and Connect). Two commands with the same opcode will never 136 // run simultaneously. 137 TransactionId SendExclusiveCommand( 138 CommandPacketVariant command_packet, 139 CommandCallbackVariant callback, 140 hci_spec::EventCode complete_event_code = 141 hci_spec::kCommandCompleteEventCode, 142 std::unordered_set<hci_spec::OpCode> exclusions = {}); 143 144 // As SendExclusiveCommand, but the transaction completes on the LE Meta Event 145 // with subevent code |le_meta_subevent_code|. 146 TransactionId SendLeAsyncExclusiveCommand( 147 CommandPacketVariant command_packet, 148 CommandCallback callback, 149 std::optional<hci_spec::EventCode> le_meta_subevent_code, 150 std::unordered_set<hci_spec::OpCode> exclusions = {}); 151 152 // If the command identified by |id| has not been sent to the controller, 153 // remove it from the send queue and return true. In this case, its 154 // CommandCallback will not be notified. If the command identified by |id| has 155 // already been sent to the controller or if it does not exist, this has no 156 // effect and returns false. 157 [[nodiscard]] bool RemoveQueuedCommand(TransactionId id); 158 159 // Used to identify an individual HCI event handler that was registered with 160 // this CommandChannel. 161 using EventHandlerId = size_t; 162 163 // Return values for EventCallbacks. 164 enum class EventCallbackResult { 165 // Continue handling this event. 166 kContinue, 167 168 // Remove this event handler. 169 // NOTE: The event callback may still be called again after it has been 170 // removed if the handler 171 // has already been posted to the dispatcher for subsequent events. 172 kRemove 173 }; 174 175 // Callbacks invoked to report generic HCI events excluding CommandComplete 176 // and CommandStatus events. 177 // 178 // TODO(fxbug.dev/42167863): Finish migration away from EventCallback and 179 // replace with EmbossEventCallback (renamed to EventCallback). 180 using EventCallback = 181 fit::function<EventCallbackResult(const EventPacket& event_packet)>; 182 using EmbossEventCallback = 183 fit::function<EventCallbackResult(const EmbossEventPacket& event_packet)>; 184 using EventCallbackVariant = std::variant<EventCallback, EmbossEventCallback>; 185 186 // Registers an event handler for HCI events that match |event_code|. Incoming 187 // HCI event packets that are not associated with a pending command sequence 188 // will be posted on the given |dispatcher| via the given |event_callback|. 189 // The returned ID can be used to unregister a previously registered event 190 // handler. 191 // 192 // |event_callback| will be invoked for all HCI event packets that match 193 // |event_code|, except for: 194 // 195 // - HCI_CommandStatus events 196 // - HCI_CommandComplete events 197 // - The completion event of the currently pending command packet, if any 198 // 199 // Returns an ID if the handler was successfully registered. Returns zero in 200 // case of an error. 201 // 202 // Multiple handlers can be registered for a given |event_code| at a time. All 203 // handlers that are registered will be called with a reference to the event. 204 // 205 // If an asynchronous command is queued which completes on |event_code|, this 206 // method returns zero. It is good practice to avoid using asynchronous 207 // commands and event handlers for the same event code. SendCommand allows 208 // for queueing multiple asynchronous commands with the same callback. 209 // Alternately a long-lived event handler can be registered with Commands 210 // completing on CommandStatus. 211 // 212 // The following values for |event_code| cannot be passed to this method: 213 // 214 // - HCI_Command_Complete event code 215 // - HCI_Command_Status event code 216 // - HCI_LE_Meta event code (use AddLEMetaEventHandler instead) 217 // - HCI_Vendor_Debug event code (use AddVendorEventHandler instead) 218 EventHandlerId AddEventHandler(hci_spec::EventCode event_code, 219 EventCallbackVariant event_callback_variant); 220 221 // Works just like AddEventHandler but the passed in event code is only valid 222 // within the LE Meta Event sub-event code namespace. |event_callback| will 223 // get invoked whenever the controller sends a LE Meta Event with a matching 224 // subevent code. 225 EventHandlerId AddLEMetaEventHandler( 226 hci_spec::EventCode le_meta_subevent_code, 227 EventCallbackVariant event_callback); 228 229 // Works just like AddEventHandler but the passed in event code is only valid 230 // for vendor related debugging events. The event_callback will get invoked 231 // whenever the controller sends one of these vendor debugging events with a 232 // matching subevent code. 233 EventHandlerId AddVendorEventHandler(hci_spec::EventCode vendor_subevent_code, 234 EventCallbackVariant event_callback); 235 236 // Removes a previously registered event handler. Does nothing if an event 237 // handler with the given |id| could not be found. 238 void RemoveEventHandler(EventHandlerId id); 239 240 // Set callback that will be called when a command times out after 241 // kCommandTimeout. This is distinct from channel closure. set_channel_timeout_cb(fit::closure timeout_cb)242 void set_channel_timeout_cb(fit::closure timeout_cb) { 243 channel_timeout_cb_ = std::move(timeout_cb); 244 } 245 246 // Attach command_channel inspect node as a child node of |parent|. 247 static constexpr const char* kInspectNodeName = "command_channel"; 248 void AttachInspect(inspect::Node& parent, 249 const std::string& name = kInspectNodeName); 250 251 using WeakPtr = WeakSelf<CommandChannel>::WeakPtr; AsWeakPtr()252 WeakPtr AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } 253 254 private: 255 TransactionId SendExclusiveCommandInternal( 256 CommandPacketVariant command_packet, 257 CommandCallbackVariant callback, 258 hci_spec::EventCode complete_event_code, 259 std::optional<hci_spec::EventCode> le_meta_subevent_code = std::nullopt, 260 std::unordered_set<hci_spec::OpCode> exclusions = {}); 261 262 // Data related to a queued or running command. 263 // 264 // When a command is sent to the controller, it is placed in the 265 // pending_transactions_ map. It remains in the pending_transactions_ map 266 // until it is completed - asynchronous commands remain until their 267 // complete_event_code_ is received. 268 // 269 // There are a number of reasons a command may be queued before sending: 270 // 271 // - An asynchronous command is waiting on the same event code 272 // - A command with an opcode that is in the exclusions set for this 273 // transaction is pending 274 // - We cannot send any commands because of the limit of outstanding command 275 // packets from the 276 // controller Queued commands are held in the send_queue_ and are sent when 277 // possible, FIFO (but skipping commands that cannot be sent) 278 class TransactionData { 279 public: 280 TransactionData(CommandChannel* channel, 281 TransactionId id, 282 hci_spec::OpCode opcode, 283 hci_spec::EventCode complete_event_code, 284 std::optional<hci_spec::EventCode> le_meta_subevent_code, 285 std::unordered_set<hci_spec::OpCode> exclusions, 286 CommandCallbackVariant callback); 287 ~TransactionData(); 288 289 // Starts the transaction timer, which will call 290 // CommandChannel::OnCommandTimeout if it's not completed in time. 291 void StartTimer(); 292 293 // Completes the transaction with |event|. For asynchronous commands, this 294 // should be called with the status event (the complete event is handled 295 // separately by the event handler). 296 void Complete(std::unique_ptr<EventPacket> event); 297 298 // Cancels the transaction timeout and erases the callback so it isn't 299 // called upon destruction. 300 void Cancel(); 301 302 // Makes an EventCallback that calls |callback_| correctly. 303 EventCallbackVariant MakeCallback(); 304 complete_event_code()305 hci_spec::EventCode complete_event_code() const { 306 return complete_event_code_; 307 } le_meta_subevent_code()308 std::optional<hci_spec::EventCode> le_meta_subevent_code() const { 309 return le_meta_subevent_code_; 310 } opcode()311 hci_spec::OpCode opcode() const { return opcode_; } id()312 TransactionId id() const { return transaction_id_; } 313 314 // The set of opcodes in progress that will hold this transaction in queue. exclusions()315 const std::unordered_set<hci_spec::OpCode>& exclusions() const { 316 return exclusions_; 317 } 318 handler_id()319 EventHandlerId handler_id() const { return handler_id_; } set_handler_id(EventHandlerId id)320 void set_handler_id(EventHandlerId id) { handler_id_ = id; } 321 322 private: 323 CommandChannel* channel_; 324 TransactionId transaction_id_; 325 hci_spec::OpCode opcode_; 326 hci_spec::EventCode complete_event_code_; 327 std::optional<hci_spec::EventCode> le_meta_subevent_code_; 328 std::unordered_set<hci_spec::OpCode> exclusions_; 329 CommandCallbackVariant callback_; 330 bt::SmartTask timeout_task_; 331 332 // If non-zero, the id of the handler registered for this transaction. 333 // Always zero if this transaction is synchronous. 334 EventHandlerId handler_id_; 335 336 BT_DISALLOW_COPY_ASSIGN_AND_MOVE(TransactionData); 337 }; 338 339 // Adds an internal event handler for |data| if one does not exist yet and 340 // another transaction is not waiting on the same event. Used to add expiring 341 // event handlers for asynchronous commands. 342 void MaybeAddTransactionHandler(TransactionData* data); 343 344 // Represents a queued command packet. 345 struct QueuedCommand { 346 QueuedCommand(CommandPacketVariant command_packet, 347 std::unique_ptr<TransactionData> data); 348 QueuedCommand() = default; 349 350 QueuedCommand(QueuedCommand&& other) = default; 351 QueuedCommand& operator=(QueuedCommand&& other) = default; 352 353 CommandPacketVariant packet; 354 std::unique_ptr<TransactionData> data; 355 }; 356 357 // Data stored for each event handler registered. 358 struct EventHandlerData { 359 EventHandlerId handler_id; 360 hci_spec::EventCode event_code; 361 362 // Defines how event_code should be interpreted. For example, if the 363 // event_type is kLEMetaEvent, the event_code is an LE Meta Subevent code. 364 EventType event_type; 365 366 // For asynchronous transaction event handlers, the pending command opcode. 367 // kNoOp if this is a static event handler. 368 hci_spec::OpCode pending_opcode; 369 370 EventCallbackVariant event_callback; 371 372 // Returns true if handler is for async command transaction, or false if 373 // handler is a static event handler. is_asyncEventHandlerData374 bool is_async() const { return pending_opcode != hci_spec::kNoOp; } 375 }; 376 377 // Finds the event handler for |code|. Returns nullptr if one doesn't exist. 378 EventHandlerData* FindEventHandler(hci_spec::EventCode code); 379 380 // Finds the LE Meta Event handler for |le_meta_subevent_code|. Returns 381 // nullptr if one doesn't exist. 382 EventHandlerData* FindLEMetaEventHandler( 383 hci_spec::EventCode le_meta_subevent_code); 384 385 // Finds the Vendor Event handler for |vendor_subevent_code|. Returns nullptr 386 // if one doesn't exist. 387 EventHandlerData* FindVendorEventHandler( 388 hci_spec::EventCode vendor_subevent_code); 389 390 // Removes internal event handler structures for |id|. 391 void RemoveEventHandlerInternal(EventHandlerId id); 392 393 // Sends any queued commands that can be processed unambiguously and complete. 394 void TrySendQueuedCommands(); 395 396 // Sends |command|, adding an internal event handler if asynchronous. 397 void SendQueuedCommand(QueuedCommand&& cmd); 398 399 // Creates a new event handler entry in the event handler map and returns its 400 // ID. The event_code should correspond to the event_type provided. For 401 // example, if event_type is kLEMetaEvent, then event_code will be interpreted 402 // as a LE Meta Subevent code. 403 EventHandlerId NewEventHandler(hci_spec::EventCode event_code, 404 EventType event_type, 405 hci_spec::OpCode pending_opcode, 406 EventCallbackVariant event_callback_variant); 407 408 // Notifies any matching event handler for |event|. 409 void NotifyEventHandler(std::unique_ptr<EventPacket> event); 410 411 // Notifies handlers for Command Status and Command Complete Events. This 412 // function marks opcodes that have transactions pending as complete by 413 // removing them and calling their callbacks. 414 void UpdateTransaction(std::unique_ptr<EventPacket> event); 415 416 // Event handler. 417 void OnEvent(pw::span<const std::byte> buffer); 418 419 // Called when a command times out. Notifies upper layers of the error. 420 void OnCommandTimeout(TransactionId transaction_id); 421 422 // True if CommandChannel is still processing packets. Set to false upon fatal 423 // errors. 424 bool active_ = true; 425 426 // Opcodes of commands that we have sent to the controller but not received a 427 // status update from. New commands with these opcodes can't be sent because 428 // they are indistinguishable from ones we need to get the result of. 429 std::unordered_map<hci_spec::OpCode, std::unique_ptr<TransactionData>> 430 pending_transactions_; 431 432 // TransactionId counter. 433 UintInspectable<TransactionId> next_transaction_id_; 434 435 // EventHandlerId counter. 436 UintInspectable<size_t> next_event_handler_id_; 437 438 // The HCI we use to send/receive HCI commands/events. 439 pw::bluetooth::Controller* hci_; 440 441 // Callback called when a command times out. 442 fit::closure channel_timeout_cb_; 443 444 // The HCI command queue. This queue is not necessarily sent in order, but 445 // commands with the same opcode or that wait on the same completion event 446 // code are sent first-in, first-out. 447 std::list<QueuedCommand> send_queue_; 448 449 // Contains the current count of commands we ae allowed to send to the 450 // controller. This is decremented when we send a command and updated when we 451 // receive a CommandStatus or CommandComplete event with the Num HCI Command 452 // Packets parameter. 453 // 454 // Accessed only from the I/O thread and thus not guarded. 455 UintInspectable<size_t> allowed_command_packets_; 456 457 // Mapping from event handler IDs to handler data. 458 std::unordered_map<EventHandlerId, EventHandlerData> event_handler_id_map_; 459 460 // Mapping from event code to the event handlers that were registered to 461 // handle that event code. 462 std::unordered_multimap<hci_spec::EventCode, EventHandlerId> 463 event_code_handlers_; 464 465 // Mapping from LE Meta Event Subevent code to the event handlers that were 466 // registered to handle that event code. 467 std::unordered_multimap<hci_spec::EventCode, EventHandlerId> 468 le_meta_subevent_code_handlers_; 469 470 // Mapping from Vendor Subevent code to the event handlers that were 471 // registered to handle that event code. 472 std::unordered_multimap<hci_spec::EventCode, EventHandlerId> 473 vendor_subevent_code_handlers_; 474 475 // Command channel inspect node. 476 inspect::Node command_channel_node_; 477 478 pw::async::Dispatcher& dispatcher_; 479 480 // As events can arrive in the event thread at any time, we should invalidate 481 // our weak pointers early. 482 WeakSelf<CommandChannel> weak_ptr_factory_; 483 484 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(CommandChannel); 485 }; 486 487 } // namespace bt::hci 488