1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2020 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef PC_SCTP_DATA_CHANNEL_H_ 12*d9f75844SAndroid Build Coastguard Worker #define PC_SCTP_DATA_CHANNEL_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <memory> 17*d9f75844SAndroid Build Coastguard Worker #include <set> 18*d9f75844SAndroid Build Coastguard Worker #include <string> 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 21*d9f75844SAndroid Build Coastguard Worker #include "api/data_channel_interface.h" 22*d9f75844SAndroid Build Coastguard Worker #include "api/priority.h" 23*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h" 24*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h" 25*d9f75844SAndroid Build Coastguard Worker #include "api/transport/data_channel_transport_interface.h" 26*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_channel.h" 27*d9f75844SAndroid Build Coastguard Worker #include "pc/data_channel_utils.h" 28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/copy_on_write_buffer.h" 29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_stream_adapter.h" // For SSLRole 30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/third_party/sigslot/sigslot.h" 31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h" 32*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 33*d9f75844SAndroid Build Coastguard Worker 34*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 35*d9f75844SAndroid Build Coastguard Worker 36*d9f75844SAndroid Build Coastguard Worker class SctpDataChannel; 37*d9f75844SAndroid Build Coastguard Worker 38*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Get rid of this and have SctpDataChannel depend on 39*d9f75844SAndroid Build Coastguard Worker // SctpTransportInternal (pure virtual SctpTransport interface) instead. 40*d9f75844SAndroid Build Coastguard Worker class SctpDataChannelControllerInterface { 41*d9f75844SAndroid Build Coastguard Worker public: 42*d9f75844SAndroid Build Coastguard Worker // Sends the data to the transport. 43*d9f75844SAndroid Build Coastguard Worker virtual bool SendData(int sid, 44*d9f75844SAndroid Build Coastguard Worker const SendDataParams& params, 45*d9f75844SAndroid Build Coastguard Worker const rtc::CopyOnWriteBuffer& payload, 46*d9f75844SAndroid Build Coastguard Worker cricket::SendDataResult* result) = 0; 47*d9f75844SAndroid Build Coastguard Worker // Connects to the transport signals. 48*d9f75844SAndroid Build Coastguard Worker virtual bool ConnectDataChannel(SctpDataChannel* data_channel) = 0; 49*d9f75844SAndroid Build Coastguard Worker // Disconnects from the transport signals. 50*d9f75844SAndroid Build Coastguard Worker virtual void DisconnectDataChannel(SctpDataChannel* data_channel) = 0; 51*d9f75844SAndroid Build Coastguard Worker // Adds the data channel SID to the transport for SCTP. 52*d9f75844SAndroid Build Coastguard Worker virtual void AddSctpDataStream(int sid) = 0; 53*d9f75844SAndroid Build Coastguard Worker // Begins the closing procedure by sending an outgoing stream reset. Still 54*d9f75844SAndroid Build Coastguard Worker // need to wait for callbacks to tell when this completes. 55*d9f75844SAndroid Build Coastguard Worker virtual void RemoveSctpDataStream(int sid) = 0; 56*d9f75844SAndroid Build Coastguard Worker // Returns true if the transport channel is ready to send data. 57*d9f75844SAndroid Build Coastguard Worker virtual bool ReadyToSendData() const = 0; 58*d9f75844SAndroid Build Coastguard Worker 59*d9f75844SAndroid Build Coastguard Worker protected: ~SctpDataChannelControllerInterface()60*d9f75844SAndroid Build Coastguard Worker virtual ~SctpDataChannelControllerInterface() {} 61*d9f75844SAndroid Build Coastguard Worker }; 62*d9f75844SAndroid Build Coastguard Worker 63*d9f75844SAndroid Build Coastguard Worker // TODO(tommi): Change to not inherit from DataChannelInit but to have it as 64*d9f75844SAndroid Build Coastguard Worker // a const member. Block access to the 'id' member since it cannot be const. 65*d9f75844SAndroid Build Coastguard Worker struct InternalDataChannelInit : public DataChannelInit { 66*d9f75844SAndroid Build Coastguard Worker enum OpenHandshakeRole { kOpener, kAcker, kNone }; 67*d9f75844SAndroid Build Coastguard Worker // The default role is kOpener because the default `negotiated` is false. InternalDataChannelInitInternalDataChannelInit68*d9f75844SAndroid Build Coastguard Worker InternalDataChannelInit() : open_handshake_role(kOpener) {} 69*d9f75844SAndroid Build Coastguard Worker explicit InternalDataChannelInit(const DataChannelInit& base); 70*d9f75844SAndroid Build Coastguard Worker OpenHandshakeRole open_handshake_role; 71*d9f75844SAndroid Build Coastguard Worker }; 72*d9f75844SAndroid Build Coastguard Worker 73*d9f75844SAndroid Build Coastguard Worker // Helper class to allocate unique IDs for SCTP DataChannels. 74*d9f75844SAndroid Build Coastguard Worker class SctpSidAllocator { 75*d9f75844SAndroid Build Coastguard Worker public: 76*d9f75844SAndroid Build Coastguard Worker // Gets the first unused odd/even id based on the DTLS role. If `role` is 77*d9f75844SAndroid Build Coastguard Worker // SSL_CLIENT, the allocated id starts from 0 and takes even numbers; 78*d9f75844SAndroid Build Coastguard Worker // otherwise, the id starts from 1 and takes odd numbers. 79*d9f75844SAndroid Build Coastguard Worker // Returns false if no ID can be allocated. 80*d9f75844SAndroid Build Coastguard Worker bool AllocateSid(rtc::SSLRole role, int* sid); 81*d9f75844SAndroid Build Coastguard Worker 82*d9f75844SAndroid Build Coastguard Worker // Attempts to reserve a specific sid. Returns false if it's unavailable. 83*d9f75844SAndroid Build Coastguard Worker bool ReserveSid(int sid); 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker // Indicates that `sid` isn't in use any more, and is thus available again. 86*d9f75844SAndroid Build Coastguard Worker void ReleaseSid(int sid); 87*d9f75844SAndroid Build Coastguard Worker 88*d9f75844SAndroid Build Coastguard Worker private: 89*d9f75844SAndroid Build Coastguard Worker // Checks if `sid` is available to be assigned to a new SCTP data channel. 90*d9f75844SAndroid Build Coastguard Worker bool IsSidAvailable(int sid) const; 91*d9f75844SAndroid Build Coastguard Worker 92*d9f75844SAndroid Build Coastguard Worker std::set<int> used_sids_; 93*d9f75844SAndroid Build Coastguard Worker }; 94*d9f75844SAndroid Build Coastguard Worker 95*d9f75844SAndroid Build Coastguard Worker // SctpDataChannel is an implementation of the DataChannelInterface based on 96*d9f75844SAndroid Build Coastguard Worker // SctpTransport. It provides an implementation of unreliable or 97*d9f75844SAndroid Build Coastguard Worker // reliabledata channels. 98*d9f75844SAndroid Build Coastguard Worker 99*d9f75844SAndroid Build Coastguard Worker // DataChannel states: 100*d9f75844SAndroid Build Coastguard Worker // kConnecting: The channel has been created the transport might not yet be 101*d9f75844SAndroid Build Coastguard Worker // ready. 102*d9f75844SAndroid Build Coastguard Worker // kOpen: The open handshake has been performed (if relevant) and the data 103*d9f75844SAndroid Build Coastguard Worker // channel is able to send messages. 104*d9f75844SAndroid Build Coastguard Worker // kClosing: DataChannelInterface::Close has been called, or the remote side 105*d9f75844SAndroid Build Coastguard Worker // initiated the closing procedure, but the closing procedure has not 106*d9f75844SAndroid Build Coastguard Worker // yet finished. 107*d9f75844SAndroid Build Coastguard Worker // kClosed: The closing handshake is finished (possibly initiated from this, 108*d9f75844SAndroid Build Coastguard Worker // side, possibly from the peer). 109*d9f75844SAndroid Build Coastguard Worker // 110*d9f75844SAndroid Build Coastguard Worker // How the closing procedure works for SCTP: 111*d9f75844SAndroid Build Coastguard Worker // 1. Alice calls Close(), state changes to kClosing. 112*d9f75844SAndroid Build Coastguard Worker // 2. Alice finishes sending any queued data. 113*d9f75844SAndroid Build Coastguard Worker // 3. Alice calls RemoveSctpDataStream, sends outgoing stream reset. 114*d9f75844SAndroid Build Coastguard Worker // 4. Bob receives incoming stream reset; OnClosingProcedureStartedRemotely 115*d9f75844SAndroid Build Coastguard Worker // called. 116*d9f75844SAndroid Build Coastguard Worker // 5. Bob sends outgoing stream reset. 117*d9f75844SAndroid Build Coastguard Worker // 6. Alice receives incoming reset, Bob receives acknowledgement. Both receive 118*d9f75844SAndroid Build Coastguard Worker // OnClosingProcedureComplete callback and transition to kClosed. 119*d9f75844SAndroid Build Coastguard Worker class SctpDataChannel : public DataChannelInterface, 120*d9f75844SAndroid Build Coastguard Worker public sigslot::has_slots<> { 121*d9f75844SAndroid Build Coastguard Worker public: 122*d9f75844SAndroid Build Coastguard Worker static rtc::scoped_refptr<SctpDataChannel> Create( 123*d9f75844SAndroid Build Coastguard Worker SctpDataChannelControllerInterface* controller, 124*d9f75844SAndroid Build Coastguard Worker const std::string& label, 125*d9f75844SAndroid Build Coastguard Worker const InternalDataChannelInit& config, 126*d9f75844SAndroid Build Coastguard Worker rtc::Thread* signaling_thread, 127*d9f75844SAndroid Build Coastguard Worker rtc::Thread* network_thread); 128*d9f75844SAndroid Build Coastguard Worker 129*d9f75844SAndroid Build Coastguard Worker // Instantiates an API proxy for a SctpDataChannel instance that will be 130*d9f75844SAndroid Build Coastguard Worker // handed out to external callers. 131*d9f75844SAndroid Build Coastguard Worker static rtc::scoped_refptr<DataChannelInterface> CreateProxy( 132*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> channel); 133*d9f75844SAndroid Build Coastguard Worker 134*d9f75844SAndroid Build Coastguard Worker // Invalidate the link to the controller (DataChannelController); 135*d9f75844SAndroid Build Coastguard Worker void DetachFromController(); 136*d9f75844SAndroid Build Coastguard Worker 137*d9f75844SAndroid Build Coastguard Worker void RegisterObserver(DataChannelObserver* observer) override; 138*d9f75844SAndroid Build Coastguard Worker void UnregisterObserver() override; 139*d9f75844SAndroid Build Coastguard Worker label()140*d9f75844SAndroid Build Coastguard Worker std::string label() const override { return label_; } 141*d9f75844SAndroid Build Coastguard Worker bool reliable() const override; ordered()142*d9f75844SAndroid Build Coastguard Worker bool ordered() const override { return config_.ordered; } 143*d9f75844SAndroid Build Coastguard Worker // Backwards compatible accessors maxRetransmitTime()144*d9f75844SAndroid Build Coastguard Worker uint16_t maxRetransmitTime() const override { 145*d9f75844SAndroid Build Coastguard Worker return config_.maxRetransmitTime ? *config_.maxRetransmitTime 146*d9f75844SAndroid Build Coastguard Worker : static_cast<uint16_t>(-1); 147*d9f75844SAndroid Build Coastguard Worker } maxRetransmits()148*d9f75844SAndroid Build Coastguard Worker uint16_t maxRetransmits() const override { 149*d9f75844SAndroid Build Coastguard Worker return config_.maxRetransmits ? *config_.maxRetransmits 150*d9f75844SAndroid Build Coastguard Worker : static_cast<uint16_t>(-1); 151*d9f75844SAndroid Build Coastguard Worker } maxPacketLifeTime()152*d9f75844SAndroid Build Coastguard Worker absl::optional<int> maxPacketLifeTime() const override { 153*d9f75844SAndroid Build Coastguard Worker return config_.maxRetransmitTime; 154*d9f75844SAndroid Build Coastguard Worker } maxRetransmitsOpt()155*d9f75844SAndroid Build Coastguard Worker absl::optional<int> maxRetransmitsOpt() const override { 156*d9f75844SAndroid Build Coastguard Worker return config_.maxRetransmits; 157*d9f75844SAndroid Build Coastguard Worker } protocol()158*d9f75844SAndroid Build Coastguard Worker std::string protocol() const override { return config_.protocol; } negotiated()159*d9f75844SAndroid Build Coastguard Worker bool negotiated() const override { return config_.negotiated; } id()160*d9f75844SAndroid Build Coastguard Worker int id() const override { return config_.id; } priority()161*d9f75844SAndroid Build Coastguard Worker Priority priority() const override { 162*d9f75844SAndroid Build Coastguard Worker return config_.priority ? *config_.priority : Priority::kLow; 163*d9f75844SAndroid Build Coastguard Worker } 164*d9f75844SAndroid Build Coastguard Worker internal_id()165*d9f75844SAndroid Build Coastguard Worker virtual int internal_id() const { return internal_id_; } 166*d9f75844SAndroid Build Coastguard Worker 167*d9f75844SAndroid Build Coastguard Worker uint64_t buffered_amount() const override; 168*d9f75844SAndroid Build Coastguard Worker void Close() override; 169*d9f75844SAndroid Build Coastguard Worker DataState state() const override; 170*d9f75844SAndroid Build Coastguard Worker RTCError error() const override; 171*d9f75844SAndroid Build Coastguard Worker uint32_t messages_sent() const override; 172*d9f75844SAndroid Build Coastguard Worker uint64_t bytes_sent() const override; 173*d9f75844SAndroid Build Coastguard Worker uint32_t messages_received() const override; 174*d9f75844SAndroid Build Coastguard Worker uint64_t bytes_received() const override; 175*d9f75844SAndroid Build Coastguard Worker bool Send(const DataBuffer& buffer) override; 176*d9f75844SAndroid Build Coastguard Worker 177*d9f75844SAndroid Build Coastguard Worker // Close immediately, ignoring any queued data or closing procedure. 178*d9f75844SAndroid Build Coastguard Worker // This is called when the underlying SctpTransport is being destroyed. 179*d9f75844SAndroid Build Coastguard Worker // It is also called by the PeerConnection if SCTP ID assignment fails. 180*d9f75844SAndroid Build Coastguard Worker void CloseAbruptlyWithError(RTCError error); 181*d9f75844SAndroid Build Coastguard Worker // Specializations of CloseAbruptlyWithError 182*d9f75844SAndroid Build Coastguard Worker void CloseAbruptlyWithDataChannelFailure(const std::string& message); 183*d9f75844SAndroid Build Coastguard Worker 184*d9f75844SAndroid Build Coastguard Worker // Slots for controller to connect signals to. 185*d9f75844SAndroid Build Coastguard Worker // 186*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): Make these private once we're hooking up signals ourselves, 187*d9f75844SAndroid Build Coastguard Worker // instead of relying on SctpDataChannelControllerInterface. 188*d9f75844SAndroid Build Coastguard Worker 189*d9f75844SAndroid Build Coastguard Worker // Called when the SctpTransport's ready to use. That can happen when we've 190*d9f75844SAndroid Build Coastguard Worker // finished negotiation, or if the channel was created after negotiation has 191*d9f75844SAndroid Build Coastguard Worker // already finished. 192*d9f75844SAndroid Build Coastguard Worker void OnTransportReady(bool writable); 193*d9f75844SAndroid Build Coastguard Worker 194*d9f75844SAndroid Build Coastguard Worker void OnDataReceived(const cricket::ReceiveDataParams& params, 195*d9f75844SAndroid Build Coastguard Worker const rtc::CopyOnWriteBuffer& payload); 196*d9f75844SAndroid Build Coastguard Worker 197*d9f75844SAndroid Build Coastguard Worker // Sets the SCTP sid and adds to transport layer if not set yet. Should only 198*d9f75844SAndroid Build Coastguard Worker // be called once. 199*d9f75844SAndroid Build Coastguard Worker void SetSctpSid(int sid); 200*d9f75844SAndroid Build Coastguard Worker // The remote side started the closing procedure by resetting its outgoing 201*d9f75844SAndroid Build Coastguard Worker // stream (our incoming stream). Sets state to kClosing. 202*d9f75844SAndroid Build Coastguard Worker void OnClosingProcedureStartedRemotely(int sid); 203*d9f75844SAndroid Build Coastguard Worker // The closing procedure is complete; both incoming and outgoing stream 204*d9f75844SAndroid Build Coastguard Worker // resets are done and the channel can transition to kClosed. Called 205*d9f75844SAndroid Build Coastguard Worker // asynchronously after RemoveSctpDataStream. 206*d9f75844SAndroid Build Coastguard Worker void OnClosingProcedureComplete(int sid); 207*d9f75844SAndroid Build Coastguard Worker // Called when the transport channel is created. 208*d9f75844SAndroid Build Coastguard Worker // Only needs to be called for SCTP data channels. 209*d9f75844SAndroid Build Coastguard Worker void OnTransportChannelCreated(); 210*d9f75844SAndroid Build Coastguard Worker // Called when the transport channel is unusable. 211*d9f75844SAndroid Build Coastguard Worker // This method makes sure the DataChannel is disconnected and changes state 212*d9f75844SAndroid Build Coastguard Worker // to kClosed. 213*d9f75844SAndroid Build Coastguard Worker void OnTransportChannelClosed(RTCError error); 214*d9f75844SAndroid Build Coastguard Worker 215*d9f75844SAndroid Build Coastguard Worker DataChannelStats GetStats() const; 216*d9f75844SAndroid Build Coastguard Worker 217*d9f75844SAndroid Build Coastguard Worker // Emitted when state transitions to kOpen. 218*d9f75844SAndroid Build Coastguard Worker sigslot::signal1<DataChannelInterface*> SignalOpened; 219*d9f75844SAndroid Build Coastguard Worker // Emitted when state transitions to kClosed. 220*d9f75844SAndroid Build Coastguard Worker // This signal can be used to tell when the channel's sid is free. 221*d9f75844SAndroid Build Coastguard Worker sigslot::signal1<DataChannelInterface*> SignalClosed; 222*d9f75844SAndroid Build Coastguard Worker 223*d9f75844SAndroid Build Coastguard Worker // Reset the allocator for internal ID values for testing, so that 224*d9f75844SAndroid Build Coastguard Worker // the internal IDs generated are predictable. Test only. 225*d9f75844SAndroid Build Coastguard Worker static void ResetInternalIdAllocatorForTesting(int new_value); 226*d9f75844SAndroid Build Coastguard Worker 227*d9f75844SAndroid Build Coastguard Worker protected: 228*d9f75844SAndroid Build Coastguard Worker SctpDataChannel(const InternalDataChannelInit& config, 229*d9f75844SAndroid Build Coastguard Worker SctpDataChannelControllerInterface* client, 230*d9f75844SAndroid Build Coastguard Worker const std::string& label, 231*d9f75844SAndroid Build Coastguard Worker rtc::Thread* signaling_thread, 232*d9f75844SAndroid Build Coastguard Worker rtc::Thread* network_thread); 233*d9f75844SAndroid Build Coastguard Worker ~SctpDataChannel() override; 234*d9f75844SAndroid Build Coastguard Worker 235*d9f75844SAndroid Build Coastguard Worker private: 236*d9f75844SAndroid Build Coastguard Worker // The OPEN(_ACK) signaling state. 237*d9f75844SAndroid Build Coastguard Worker enum HandshakeState { 238*d9f75844SAndroid Build Coastguard Worker kHandshakeInit, 239*d9f75844SAndroid Build Coastguard Worker kHandshakeShouldSendOpen, 240*d9f75844SAndroid Build Coastguard Worker kHandshakeShouldSendAck, 241*d9f75844SAndroid Build Coastguard Worker kHandshakeWaitingForAck, 242*d9f75844SAndroid Build Coastguard Worker kHandshakeReady 243*d9f75844SAndroid Build Coastguard Worker }; 244*d9f75844SAndroid Build Coastguard Worker 245*d9f75844SAndroid Build Coastguard Worker bool Init(); 246*d9f75844SAndroid Build Coastguard Worker void UpdateState(); 247*d9f75844SAndroid Build Coastguard Worker void SetState(DataState state); 248*d9f75844SAndroid Build Coastguard Worker void DisconnectFromTransport(); 249*d9f75844SAndroid Build Coastguard Worker 250*d9f75844SAndroid Build Coastguard Worker void DeliverQueuedReceivedData(); 251*d9f75844SAndroid Build Coastguard Worker 252*d9f75844SAndroid Build Coastguard Worker void SendQueuedDataMessages(); 253*d9f75844SAndroid Build Coastguard Worker bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked); 254*d9f75844SAndroid Build Coastguard Worker bool QueueSendDataMessage(const DataBuffer& buffer); 255*d9f75844SAndroid Build Coastguard Worker 256*d9f75844SAndroid Build Coastguard Worker void SendQueuedControlMessages(); 257*d9f75844SAndroid Build Coastguard Worker void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer); 258*d9f75844SAndroid Build Coastguard Worker bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer); 259*d9f75844SAndroid Build Coastguard Worker 260*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const signaling_thread_; 261*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const network_thread_; 262*d9f75844SAndroid Build Coastguard Worker const int internal_id_; 263*d9f75844SAndroid Build Coastguard Worker const std::string label_; 264*d9f75844SAndroid Build Coastguard Worker const InternalDataChannelInit config_; 265*d9f75844SAndroid Build Coastguard Worker DataChannelObserver* observer_ RTC_GUARDED_BY(signaling_thread_) = nullptr; 266*d9f75844SAndroid Build Coastguard Worker DataState state_ RTC_GUARDED_BY(signaling_thread_) = kConnecting; 267*d9f75844SAndroid Build Coastguard Worker RTCError error_ RTC_GUARDED_BY(signaling_thread_); 268*d9f75844SAndroid Build Coastguard Worker uint32_t messages_sent_ RTC_GUARDED_BY(signaling_thread_) = 0; 269*d9f75844SAndroid Build Coastguard Worker uint64_t bytes_sent_ RTC_GUARDED_BY(signaling_thread_) = 0; 270*d9f75844SAndroid Build Coastguard Worker uint32_t messages_received_ RTC_GUARDED_BY(signaling_thread_) = 0; 271*d9f75844SAndroid Build Coastguard Worker uint64_t bytes_received_ RTC_GUARDED_BY(signaling_thread_) = 0; 272*d9f75844SAndroid Build Coastguard Worker SctpDataChannelControllerInterface* const controller_ 273*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(signaling_thread_); 274*d9f75844SAndroid Build Coastguard Worker bool controller_detached_ RTC_GUARDED_BY(signaling_thread_) = false; 275*d9f75844SAndroid Build Coastguard Worker HandshakeState handshake_state_ RTC_GUARDED_BY(signaling_thread_) = 276*d9f75844SAndroid Build Coastguard Worker kHandshakeInit; 277*d9f75844SAndroid Build Coastguard Worker bool connected_to_transport_ RTC_GUARDED_BY(signaling_thread_) = false; 278*d9f75844SAndroid Build Coastguard Worker bool writable_ RTC_GUARDED_BY(signaling_thread_) = false; 279*d9f75844SAndroid Build Coastguard Worker // Did we already start the graceful SCTP closing procedure? 280*d9f75844SAndroid Build Coastguard Worker bool started_closing_procedure_ RTC_GUARDED_BY(signaling_thread_) = false; 281*d9f75844SAndroid Build Coastguard Worker // Control messages that always have to get sent out before any queued 282*d9f75844SAndroid Build Coastguard Worker // data. 283*d9f75844SAndroid Build Coastguard Worker PacketQueue queued_control_data_ RTC_GUARDED_BY(signaling_thread_); 284*d9f75844SAndroid Build Coastguard Worker PacketQueue queued_received_data_ RTC_GUARDED_BY(signaling_thread_); 285*d9f75844SAndroid Build Coastguard Worker PacketQueue queued_send_data_ RTC_GUARDED_BY(signaling_thread_); 286*d9f75844SAndroid Build Coastguard Worker }; 287*d9f75844SAndroid Build Coastguard Worker 288*d9f75844SAndroid Build Coastguard Worker // Downcast a PeerConnectionInterface that points to a proxy object 289*d9f75844SAndroid Build Coastguard Worker // to its underlying SctpDataChannel object. For testing only. 290*d9f75844SAndroid Build Coastguard Worker SctpDataChannel* DowncastProxiedDataChannelInterfaceToSctpDataChannelForTesting( 291*d9f75844SAndroid Build Coastguard Worker DataChannelInterface* channel); 292*d9f75844SAndroid Build Coastguard Worker 293*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 294*d9f75844SAndroid Build Coastguard Worker 295*d9f75844SAndroid Build Coastguard Worker #endif // PC_SCTP_DATA_CHANNEL_H_ 296