data_channel_interface.h (9201B)
1 /* 2 * Copyright 2012 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 // This file contains interfaces for DataChannels 12 // http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannel 13 14 #ifndef API_DATA_CHANNEL_INTERFACE_H_ 15 #define API_DATA_CHANNEL_INTERFACE_H_ 16 17 #include <stddef.h> 18 #include <stdint.h> 19 20 #include <optional> 21 #include <string> 22 23 #include "absl/functional/any_invocable.h" 24 #include "api/priority.h" 25 #include "api/ref_count.h" 26 #include "api/rtc_error.h" 27 #include "rtc_base/checks.h" 28 #include "rtc_base/copy_on_write_buffer.h" 29 #include "rtc_base/system/rtc_export.h" 30 31 namespace webrtc { 32 33 // C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelinit 34 // TODO(deadbeef): Use std::optional for the "-1 if unset" things. 35 #if defined(__clang__) 36 #pragma clang diagnostic push 37 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 38 #endif 39 struct DataChannelInit { 40 // Deprecated. Reliability is assumed, and channel will be unreliable if 41 // maxRetransmitTime or MaxRetransmits is set. 42 bool reliable = false; 43 44 // True if ordered delivery is required. 45 bool ordered = true; 46 47 // The max period of time in milliseconds in which retransmissions will be 48 // sent. After this time, no more retransmissions will be sent. 49 // 50 // Cannot be set along with `maxRetransmits`. 51 // This is called `maxPacketLifeTime` in the WebRTC JS API. 52 // Negative values are ignored, and positive values are clamped to [0-65535] 53 std::optional<int> maxRetransmitTime; 54 55 // The max number of retransmissions. 56 // 57 // Cannot be set along with `maxRetransmitTime`. 58 // Negative values are ignored, and positive values are clamped to [0-65535] 59 std::optional<int> maxRetransmits; 60 61 // This is set by the application and opaque to the WebRTC implementation. 62 std::string protocol; 63 64 // True if the channel has been externally negotiated and we do not send an 65 // in-band signalling in the form of an "open" message. If this is true, `id` 66 // below must be set; otherwise it should be unset and will be negotiated 67 // in-band. 68 bool negotiated = false; 69 70 // The stream id, or SID, for SCTP data channels. -1 if unset (see above). 71 int id = -1; 72 73 // https://w3c.github.io/webrtc-priority/#new-rtcdatachannelinit-member 74 std::optional<PriorityValue> priority; 75 }; 76 #if defined(__clang__) 77 #pragma clang diagnostic pop 78 #endif 79 80 // At the JavaScript level, data can be passed in as a string or a blob, so 81 // this structure's `binary` flag tells whether the data should be interpreted 82 // as binary or text. 83 struct DataBuffer { 84 DataBuffer(const CopyOnWriteBuffer& data, bool binary) 85 : data(data), binary(binary) {} 86 // For convenience for unit tests. 87 explicit DataBuffer(const std::string& text) 88 : data(text.data(), text.length()), binary(false) {} 89 size_t size() const { return data.size(); } 90 91 CopyOnWriteBuffer data; 92 // Indicates if the received data contains UTF-8 or binary data. 93 // Note that the upper layers are left to verify the UTF-8 encoding. 94 // TODO(jiayl): prefer to use an enum instead of a bool. 95 bool binary; 96 }; 97 98 // Used to implement RTCDataChannel events. 99 // 100 // The code responding to these callbacks should unwind the stack before 101 // using any other webrtc APIs; re-entrancy is not supported. 102 class DataChannelObserver { 103 public: 104 // The data channel state have changed. 105 virtual void OnStateChange() = 0; 106 // A data buffer was successfully received. 107 virtual void OnMessage(const DataBuffer& buffer) = 0; 108 // The data channel's buffered_amount has changed. 109 virtual void OnBufferedAmountChange(uint64_t /* sent_data_size */) {} 110 111 // Override this to get callbacks directly on the network thread. 112 // An implementation that does that must not block the network thread 113 // but rather only use the callback to trigger asynchronous processing 114 // elsewhere as a result of the notification. 115 // The default return value, `false`, means that notifications will be 116 // delivered on the signaling thread associated with the peerconnection 117 // instance. 118 // TODO(webrtc:11547): Eventually all DataChannelObserver implementations 119 // should be called on the network thread and this method removed. 120 virtual bool IsOkToCallOnTheNetworkThread() { return false; } 121 122 protected: 123 virtual ~DataChannelObserver() = default; 124 }; 125 126 class RTC_EXPORT DataChannelInterface : public RefCountInterface { 127 public: 128 // C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelstate 129 // Unlikely to change, but keep in sync with DataChannel.java:State and 130 // RTCDataChannel.h:RTCDataChannelState. 131 enum DataState { 132 kConnecting, 133 kOpen, // The DataChannel is ready to send data. 134 kClosing, 135 kClosed 136 }; 137 138 static const char* DataStateString(DataState state) { 139 switch (state) { 140 case kConnecting: 141 return "connecting"; 142 case kOpen: 143 return "open"; 144 case kClosing: 145 return "closing"; 146 case kClosed: 147 return "closed"; 148 } 149 RTC_CHECK(false) << "Unknown DataChannel state: " << state; 150 return ""; 151 } 152 153 // Used to receive events from the data channel. Only one observer can be 154 // registered at a time. UnregisterObserver should be called before the 155 // observer object is destroyed. 156 virtual void RegisterObserver(DataChannelObserver* observer) = 0; 157 virtual void UnregisterObserver() = 0; 158 159 // The label attribute represents a label that can be used to distinguish this 160 // DataChannel object from other DataChannel objects. 161 virtual std::string label() const = 0; 162 163 // The accessors below simply return the properties from the DataChannelInit 164 // the data channel was constructed with. 165 virtual bool reliable() const = 0; 166 // TODO(deadbeef): Remove these dummy implementations when all classes have 167 // implemented these APIs. They should all just return the values the 168 // DataChannel was created with. 169 virtual bool ordered() const; 170 virtual std::optional<int> maxRetransmitsOpt() const; 171 virtual std::optional<int> maxPacketLifeTime() const; 172 virtual std::string protocol() const; 173 virtual bool negotiated() const; 174 175 // Returns the ID from the DataChannelInit, if it was negotiated out-of-band. 176 // If negotiated in-band, this ID will be populated once the DTLS role is 177 // determined, and until then this will return -1. 178 virtual int id() const = 0; 179 virtual PriorityValue priority() const; 180 virtual DataState state() const = 0; 181 // When state is kClosed, and the DataChannel was not closed using 182 // the closing procedure, returns the error information about the closing. 183 // The default implementation returns "no error". 184 virtual RTCError error() const { return RTCError(); } 185 virtual uint32_t messages_sent() const = 0; 186 virtual uint64_t bytes_sent() const = 0; 187 virtual uint32_t messages_received() const = 0; 188 virtual uint64_t bytes_received() const = 0; 189 190 // Returns the number of bytes of application data (UTF-8 text and binary 191 // data) that have been queued using Send but have not yet been processed at 192 // the SCTP level. See comment above Send below. 193 // Values are less or equal to MaxSendQueueSize(). 194 virtual uint64_t buffered_amount() const = 0; 195 196 // Begins the graceful data channel closing procedure. See: 197 // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.7 198 virtual void Close() = 0; 199 200 // Sends `data` to the remote peer. If the data can't be sent at the SCTP 201 // level (due to congestion control), it's buffered at the data channel level, 202 // up to a maximum of MaxSendQueueSize(). 203 // Returns false if the data channel is not in open state or if the send 204 // buffer is full. 205 // TODO(webrtc:13289): Return an RTCError with information about the failure. 206 // TODO(tommi): Remove this method once downstream implementations don't refer 207 // to it. 208 virtual bool Send(const DataBuffer& buffer); 209 210 // Queues up an asynchronus send operation to run on a network thread. 211 // Once the operation has completed the `on_complete` callback is invoked, 212 // on the thread the send operation was done on. It's important that 213 // `on_complete` implementations do not block the current thread but rather 214 // post any expensive operations to other worker threads. 215 // TODO(tommi): Make pure virtual after updating mock class in Chromium. 216 // Deprecate `Send` in favor of this variant since the return value of `Send` 217 // is limiting for a fully async implementation (yet in practice is ignored). 218 virtual void SendAsync(DataBuffer buffer, 219 absl::AnyInvocable<void(RTCError) &&> on_complete); 220 221 // Amount of bytes that can be queued for sending on the data channel. 222 // Those are bytes that have not yet been processed at the SCTP level. 223 static uint64_t MaxSendQueueSize(); 224 225 protected: 226 ~DataChannelInterface() override = default; 227 }; 228 229 } // namespace webrtc 230 231 #endif // API_DATA_CHANNEL_INTERFACE_H_