1 // Copyright 2024 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/moqt/moqt_subscribe_windows.h"
6
7 #include <cstdint>
8 #include <optional>
9 #include <vector>
10
11 #include "quiche/quic/moqt/moqt_messages.h"
12 #include "quiche/quic/platform/api/quic_bug_tracker.h"
13 #include "quiche/web_transport/web_transport.h"
14
15 namespace moqt {
16
InWindow(const FullSequence & seq) const17 bool SubscribeWindow::InWindow(const FullSequence& seq) const {
18 if (seq < start_) {
19 return false;
20 }
21 return (!end_.has_value() || seq <= *end_);
22 }
23
GetStreamForSequence(FullSequence sequence) const24 std::optional<webtransport::StreamId> SubscribeWindow::GetStreamForSequence(
25 FullSequence sequence) const {
26 FullSequence index = SequenceToIndex(sequence);
27 auto stream_it = send_streams_.find(index);
28 if (stream_it == send_streams_.end()) {
29 return std::nullopt;
30 }
31 return stream_it->second;
32 }
33
AddStream(uint64_t group_id,uint64_t object_id,webtransport::StreamId stream_id)34 void SubscribeWindow::AddStream(uint64_t group_id, uint64_t object_id,
35 webtransport::StreamId stream_id) {
36 if (!InWindow(FullSequence(group_id, object_id))) {
37 return;
38 }
39 FullSequence index = SequenceToIndex(FullSequence(group_id, object_id));
40 if (forwarding_preference_ == MoqtForwardingPreference::kDatagram) {
41 QUIC_BUG(quic_bug_moqt_draft_03_01) << "Adding a stream for datagram";
42 return;
43 }
44 auto stream_it = send_streams_.find(index);
45 if (stream_it != send_streams_.end()) {
46 QUIC_BUG(quic_bug_moqt_draft_03_02) << "Stream already added";
47 return;
48 }
49 send_streams_[index] = stream_id;
50 }
51
RemoveStream(uint64_t group_id,uint64_t object_id)52 void SubscribeWindow::RemoveStream(uint64_t group_id, uint64_t object_id) {
53 FullSequence index = SequenceToIndex(FullSequence(group_id, object_id));
54 send_streams_.erase(index);
55 }
56
SequenceToIndex(FullSequence sequence) const57 FullSequence SubscribeWindow::SequenceToIndex(FullSequence sequence) const {
58 switch (forwarding_preference_) {
59 case MoqtForwardingPreference::kTrack:
60 return FullSequence(0, 0);
61 case MoqtForwardingPreference::kGroup:
62 return FullSequence(sequence.group, 0);
63 case MoqtForwardingPreference::kObject:
64 return sequence;
65 case MoqtForwardingPreference::kDatagram:
66 QUIC_BUG(quic_bug_moqt_draft_03_01) << "No stream for datagram";
67 return FullSequence(0, 0);
68 }
69 }
70
SequenceIsSubscribed(FullSequence sequence)71 std::vector<SubscribeWindow*> MoqtSubscribeWindows::SequenceIsSubscribed(
72 FullSequence sequence) {
73 std::vector<SubscribeWindow*> retval;
74 for (auto& [subscribe_id, window] : windows_) {
75 if (window.InWindow(sequence)) {
76 retval.push_back(&(window));
77 }
78 }
79 return retval;
80 }
81
82 } // namespace moqt
83