xref: /aosp_15_r20/external/webrtc/pc/rtcp_mux_filter.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2004 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "pc/rtcp_mux_filter.h"
12 
13 #include "rtc_base/logging.h"
14 
15 namespace cricket {
16 
RtcpMuxFilter()17 RtcpMuxFilter::RtcpMuxFilter() : state_(ST_INIT), offer_enable_(false) {}
18 
IsFullyActive() const19 bool RtcpMuxFilter::IsFullyActive() const {
20   return state_ == ST_ACTIVE;
21 }
22 
IsProvisionallyActive() const23 bool RtcpMuxFilter::IsProvisionallyActive() const {
24   return state_ == ST_SENTPRANSWER || state_ == ST_RECEIVEDPRANSWER;
25 }
26 
IsActive() const27 bool RtcpMuxFilter::IsActive() const {
28   return IsFullyActive() || IsProvisionallyActive();
29 }
30 
SetActive()31 void RtcpMuxFilter::SetActive() {
32   state_ = ST_ACTIVE;
33 }
34 
SetOffer(bool offer_enable,ContentSource src)35 bool RtcpMuxFilter::SetOffer(bool offer_enable, ContentSource src) {
36   if (state_ == ST_ACTIVE) {
37     // Fail if we try to deactivate and no-op if we try and activate.
38     return offer_enable;
39   }
40 
41   if (!ExpectOffer(offer_enable, src)) {
42     RTC_LOG(LS_ERROR) << "Invalid state for change of RTCP mux offer";
43     return false;
44   }
45 
46   offer_enable_ = offer_enable;
47   state_ = (src == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
48   return true;
49 }
50 
SetProvisionalAnswer(bool answer_enable,ContentSource src)51 bool RtcpMuxFilter::SetProvisionalAnswer(bool answer_enable,
52                                          ContentSource src) {
53   if (state_ == ST_ACTIVE) {
54     // Fail if we try to deactivate and no-op if we try and activate.
55     return answer_enable;
56   }
57 
58   if (!ExpectAnswer(src)) {
59     RTC_LOG(LS_ERROR) << "Invalid state for RTCP mux provisional answer";
60     return false;
61   }
62 
63   if (offer_enable_) {
64     if (answer_enable) {
65       if (src == CS_REMOTE)
66         state_ = ST_RECEIVEDPRANSWER;
67       else  // CS_LOCAL
68         state_ = ST_SENTPRANSWER;
69     } else {
70       // The provisional answer doesn't want to use RTCP mux.
71       // Go back to the original state after the offer was set and wait for next
72       // provisional or final answer.
73       if (src == CS_REMOTE)
74         state_ = ST_SENTOFFER;
75       else  // CS_LOCAL
76         state_ = ST_RECEIVEDOFFER;
77     }
78   } else if (answer_enable) {
79     // If the offer didn't specify RTCP mux, the answer shouldn't either.
80     RTC_LOG(LS_WARNING) << "Invalid parameters in RTCP mux provisional answer";
81     return false;
82   }
83 
84   return true;
85 }
86 
SetAnswer(bool answer_enable,ContentSource src)87 bool RtcpMuxFilter::SetAnswer(bool answer_enable, ContentSource src) {
88   if (state_ == ST_ACTIVE) {
89     // Fail if we try to deactivate and no-op if we try and activate.
90     return answer_enable;
91   }
92 
93   if (!ExpectAnswer(src)) {
94     RTC_LOG(LS_ERROR) << "Invalid state for RTCP mux answer, state is "
95                       << state_ << ", source is " << src;
96     return false;
97   }
98 
99   if (offer_enable_ && answer_enable) {
100     state_ = ST_ACTIVE;
101   } else if (answer_enable) {
102     // If the offer didn't specify RTCP mux, the answer shouldn't either.
103     RTC_LOG(LS_WARNING) << "Invalid parameters in RTCP mux answer";
104     return false;
105   } else {
106     state_ = ST_INIT;
107   }
108   return true;
109 }
110 
ExpectOffer(bool offer_enable,ContentSource source)111 bool RtcpMuxFilter::ExpectOffer(bool offer_enable, ContentSource source) {
112   return ((state_ == ST_INIT) ||
113           (state_ == ST_ACTIVE && offer_enable == offer_enable_) ||
114           (state_ == ST_SENTOFFER && source == CS_LOCAL) ||
115           (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE));
116 }
117 
ExpectAnswer(ContentSource source)118 bool RtcpMuxFilter::ExpectAnswer(ContentSource source) {
119   return ((state_ == ST_SENTOFFER && source == CS_REMOTE) ||
120           (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) ||
121           (state_ == ST_SENTPRANSWER && source == CS_LOCAL) ||
122           (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE));
123 }
124 
125 }  // namespace cricket
126