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_bluetooth_sapphire/internal/host/common/weak_self.h" 18 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" 19 #include "pw_bluetooth_sapphire/internal/host/iso/iso_common.h" 20 #include "pw_bluetooth_sapphire/internal/host/iso/iso_stream.h" 21 #include "pw_bluetooth_sapphire/internal/host/transport/command_channel.h" 22 #include "pw_bluetooth_sapphire/internal/host/transport/transport.h" 23 24 namespace bt::iso { 25 26 // Responsible for owning and managing IsoStream objects associated with a 27 // single LE connection. 28 // When operating as a Central, establishes an outgoing streams. When operating 29 // as a Peripheral, processes incoming stream requests . 30 class IsoStreamManager final { 31 public: 32 explicit IsoStreamManager(hci_spec::ConnectionHandle handle, 33 hci::Transport::WeakPtr hci); 34 ~IsoStreamManager(); 35 36 // Start waiting on an incoming request to create an Isochronous channel for 37 // the specified CIG/CIS |id|. If we are already waiting on |id|, or if a 38 // stream has already been established with the given |id|, returns 39 // kAlreadyExists. |cb| will be invoked when we receive an incoming ISO 40 // channel request with a matching CIG/CIS |id|, and will indicate the status 41 // of establishing a channel and on success the associated channel parameters. 42 [[nodiscard]] AcceptCisStatus AcceptCis(CigCisIdentifier id, 43 CisEstablishedCallback cb); 44 45 // Indicates if we are currently waiting on a connection for the specified 46 // CIG/CIS combination HandlerRegistered(const CigCisIdentifier & id)47 bool HandlerRegistered(const CigCisIdentifier& id) const { 48 return accept_handlers_.count(id) != 0; 49 } 50 51 using WeakPtr = WeakSelf<IsoStreamManager>::WeakPtr; GetWeakPtr()52 IsoStreamManager::WeakPtr GetWeakPtr() { return weak_self_.GetWeakPtr(); } 53 54 private: 55 // Process an incoming CIS request. Currently rejects all requests. 56 void OnCisRequest(const hci::EventPacket& event); 57 58 // Process a disconnection and shut down a CIS. 59 void OnDisconnect(const hci::EventPacket& event); 60 61 void AcceptCisRequest( 62 const pw::bluetooth::emboss::LECISRequestSubeventView& event_view, 63 CisEstablishedCallback cb); 64 65 // Send a rejection in response to an incoming CIS request. 66 void RejectCisRequest( 67 const pw::bluetooth::emboss::LECISRequestSubeventView& event_view); 68 69 hci_spec::ConnectionHandle acl_handle_; 70 71 // LE event handler for incoming CIS requests 72 hci::CommandChannel::EventHandlerId cis_request_handler_; 73 // Event handler for disconnect events 74 hci::CommandChannel::EventHandlerId disconnect_handler_; 75 76 hci::CommandChannel::WeakPtr cmd_; 77 78 hci::Transport::WeakPtr hci_; 79 80 // The streams that we are currently waiting on, and the associated callback 81 // when the connection is resolved (either accepted and established, or failed 82 // to establish). 83 std::unordered_map<CigCisIdentifier, CisEstablishedCallback> accept_handlers_; 84 85 // All of the allocated streams. 86 std::unordered_map<CigCisIdentifier, std::unique_ptr<IsoStream>> streams_; 87 88 WeakSelf<IsoStreamManager> weak_self_; 89 90 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(IsoStreamManager); 91 }; 92 93 } // namespace bt::iso 94