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 <cstdint>
18 
19 #include "pw_bluetooth_sapphire/internal/host/common/weak_self.h"
20 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
21 #include "pw_bluetooth_sapphire/internal/host/iso/iso_common.h"
22 #include "pw_bluetooth_sapphire/internal/host/transport/command_channel.h"
23 #include "pw_bluetooth_sapphire/internal/host/transport/transport.h"
24 
25 namespace bt::iso {
26 
27 class IsoStream : public hci::IsoDataChannel::ConnectionInterface {
28  public:
29   virtual ~IsoStream() = default;
30 
31   // Handler for incoming HCI_LE_CIS_Established events. Returns a value
32   // indicating whether the vent was handled.
33   virtual bool OnCisEstablished(const hci::EventPacket& event) = 0;
34 
35   enum SetupDataPathError {
36     kSuccess,
37     kStreamAlreadyExists,
38     kCisNotEstablished,
39     kStreamRejectedByController,
40     kInvalidArgs,
41     kStreamClosed,
42   };
43 
44   using SetupDataPathCallback = pw::Callback<void(SetupDataPathError)>;
45   using IncomingDataHandler =
46       pw::Function<bool(const pw::span<const std::byte>&)>;
47 
48   virtual void SetupDataPath(
49       pw::bluetooth::emboss::DataPathDirection direction,
50       const bt::StaticPacket<pw::bluetooth::emboss::CodecIdWriter>& codec_id,
51       const std::optional<std::vector<uint8_t>>& codec_configuration,
52       uint32_t controller_delay_usecs,
53       SetupDataPathCallback&& on_complete_cb,
54       IncomingDataHandler&& on_incoming_data_available_cb) = 0;
55 
56   virtual hci_spec::ConnectionHandle cis_handle() const = 0;
57 
58   // Terminate this stream.
59   virtual void Close() = 0;
60 
61   static std::unique_ptr<IsoStream> Create(
62       uint8_t cig_id,
63       uint8_t cis_id,
64       hci_spec::ConnectionHandle cis_handle,
65       CisEstablishedCallback on_established_cb,
66       hci::CommandChannel::WeakPtr cmd,
67       pw::Callback<void()> on_closed_cb);
68 
69   // Used by the client to check for queued frames. If none are present the
70   // incoming data available callback will be called the next time a frame is
71   // available. This allows for a 'hanging get' style interface (request a frame
72   // whenever the client is ready to process one and then wait for a
73   // notification) or a client-buffered interface (every time the client wants
74   // more frames request them until it receives a nullptr, and then wait for a
75   // callback to indicate that the next frame(s) are available). It is important
76   // to note that the client cannot simply rely on notifications: until a read
77   // attempt is unfulfilled the stream will buffer frames waiting for a read
78   // from the client.
79   virtual std::unique_ptr<IsoDataPacket> ReadNextQueuedIncomingPacket() = 0;
80 
81   using WeakPtr = WeakSelf<IsoStream>::WeakPtr;
82   virtual WeakPtr GetWeakPtr() = 0;
83 };
84 
85 }  // namespace bt::iso
86