blob: 1af90dab6e3ab37655bdee6a9e9eb139e28a40db [file] [log] [blame]
ossu7bb87ee2017-01-23 04:56:25 -08001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef PC_DATACHANNEL_H_
12#define PC_DATACHANNEL_H_
ossu7bb87ee2017-01-23 04:56:25 -080013
14#include <deque>
15#include <set>
16#include <string>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/datachannelinterface.h"
19#include "api/proxy.h"
20#include "media/base/mediachannel.h"
21#include "pc/channel.h"
22#include "rtc_base/messagehandler.h"
23#include "rtc_base/scoped_ref_ptr.h"
24#include "rtc_base/sigslot.h"
ossu7bb87ee2017-01-23 04:56:25 -080025
26namespace webrtc {
27
28class DataChannel;
29
30class DataChannelProviderInterface {
31 public:
32 // Sends the data to the transport.
33 virtual bool SendData(const cricket::SendDataParams& params,
34 const rtc::CopyOnWriteBuffer& payload,
35 cricket::SendDataResult* result) = 0;
36 // Connects to the transport signals.
37 virtual bool ConnectDataChannel(DataChannel* data_channel) = 0;
38 // Disconnects from the transport signals.
39 virtual void DisconnectDataChannel(DataChannel* data_channel) = 0;
40 // Adds the data channel SID to the transport for SCTP.
41 virtual void AddSctpDataStream(int sid) = 0;
42 // Removes the data channel SID from the transport for SCTP.
43 virtual void RemoveSctpDataStream(int sid) = 0;
44 // Returns true if the transport channel is ready to send data.
45 virtual bool ReadyToSendData() const = 0;
46
47 protected:
48 virtual ~DataChannelProviderInterface() {}
49};
50
51struct InternalDataChannelInit : public DataChannelInit {
52 enum OpenHandshakeRole {
53 kOpener,
54 kAcker,
55 kNone
56 };
57 // The default role is kOpener because the default |negotiated| is false.
58 InternalDataChannelInit() : open_handshake_role(kOpener) {}
59 explicit InternalDataChannelInit(const DataChannelInit& base)
60 : DataChannelInit(base), open_handshake_role(kOpener) {
61 // If the channel is externally negotiated, do not send the OPEN message.
62 if (base.negotiated) {
63 open_handshake_role = kNone;
64 }
65 }
66
67 OpenHandshakeRole open_handshake_role;
68};
69
70// Helper class to allocate unique IDs for SCTP DataChannels
71class SctpSidAllocator {
72 public:
73 // Gets the first unused odd/even id based on the DTLS role. If |role| is
74 // SSL_CLIENT, the allocated id starts from 0 and takes even numbers;
75 // otherwise, the id starts from 1 and takes odd numbers.
76 // Returns false if no id can be allocated.
77 bool AllocateSid(rtc::SSLRole role, int* sid);
78
79 // Attempts to reserve a specific sid. Returns false if it's unavailable.
80 bool ReserveSid(int sid);
81
82 // Indicates that |sid| isn't in use any more, and is thus available again.
83 void ReleaseSid(int sid);
84
85 private:
86 // Checks if |sid| is available to be assigned to a new SCTP data channel.
87 bool IsSidAvailable(int sid) const;
88
89 std::set<int> used_sids_;
90};
91
92// DataChannel is a an implementation of the DataChannelInterface based on
93// libjingle's data engine. It provides an implementation of unreliable or
94// reliabledata channels. Currently this class is specifically designed to use
95// both RtpDataEngine and SctpDataEngine.
96
97// DataChannel states:
98// kConnecting: The channel has been created the transport might not yet be
99// ready.
100// kOpen: The channel have a local SSRC set by a call to UpdateSendSsrc
101// and a remote SSRC set by call to UpdateReceiveSsrc and the transport
102// has been writable once.
103// kClosing: DataChannelInterface::Close has been called or UpdateReceiveSsrc
104// has been called with SSRC==0
105// kClosed: Both UpdateReceiveSsrc and UpdateSendSsrc has been called with
106// SSRC==0.
107class DataChannel : public DataChannelInterface,
108 public sigslot::has_slots<>,
109 public rtc::MessageHandler {
110 public:
111 static rtc::scoped_refptr<DataChannel> Create(
112 DataChannelProviderInterface* provider,
113 cricket::DataChannelType dct,
114 const std::string& label,
115 const InternalDataChannelInit& config);
116
117 virtual void RegisterObserver(DataChannelObserver* observer);
118 virtual void UnregisterObserver();
119
120 virtual std::string label() const { return label_; }
121 virtual bool reliable() const;
122 virtual bool ordered() const { return config_.ordered; }
123 virtual uint16_t maxRetransmitTime() const {
124 return config_.maxRetransmitTime;
125 }
126 virtual uint16_t maxRetransmits() const { return config_.maxRetransmits; }
127 virtual std::string protocol() const { return config_.protocol; }
128 virtual bool negotiated() const { return config_.negotiated; }
129 virtual int id() const { return config_.id; }
130 virtual uint64_t buffered_amount() const;
131 virtual void Close();
132 virtual DataState state() const { return state_; }
133 virtual uint32_t messages_sent() const { return messages_sent_; }
134 virtual uint64_t bytes_sent() const { return bytes_sent_; }
135 virtual uint32_t messages_received() const { return messages_received_; }
136 virtual uint64_t bytes_received() const { return bytes_received_; }
137 virtual bool Send(const DataBuffer& buffer);
138
139 // rtc::MessageHandler override.
140 virtual void OnMessage(rtc::Message* msg);
141
142 // Called when the channel's ready to use. That can happen when the
143 // underlying DataMediaChannel becomes ready, or when this channel is a new
144 // stream on an existing DataMediaChannel, and we've finished negotiation.
145 void OnChannelReady(bool writable);
146
147 // Slots for provider to connect signals to.
148 void OnDataReceived(const cricket::ReceiveDataParams& params,
149 const rtc::CopyOnWriteBuffer& payload);
150 void OnStreamClosedRemotely(int sid);
151
152 // The remote peer request that this channel should be closed.
153 void RemotePeerRequestClose();
154
155 // The following methods are for SCTP only.
156
157 // Sets the SCTP sid and adds to transport layer if not set yet. Should only
158 // be called once.
159 void SetSctpSid(int sid);
160 // Called when the transport channel is created.
161 // Only needs to be called for SCTP data channels.
162 void OnTransportChannelCreated();
163 // Called when the transport channel is destroyed.
164 // This method makes sure the DataChannel is disconnected and changes state
165 // to kClosed.
166 void OnTransportChannelDestroyed();
167
168 // The following methods are for RTP only.
169
170 // Set the SSRC this channel should use to send data on the
171 // underlying data engine. |send_ssrc| == 0 means that the channel is no
172 // longer part of the session negotiation.
173 void SetSendSsrc(uint32_t send_ssrc);
174 // Set the SSRC this channel should use to receive data from the
175 // underlying data engine.
176 void SetReceiveSsrc(uint32_t receive_ssrc);
177
178 cricket::DataChannelType data_channel_type() const {
179 return data_channel_type_;
180 }
181
182 // Emitted when state transitions to kOpen.
183 sigslot::signal1<DataChannel*> SignalOpened;
184 // Emitted when state transitions to kClosed.
185 // In the case of SCTP channels, this signal can be used to tell when the
186 // channel's sid is free.
187 sigslot::signal1<DataChannel*> SignalClosed;
188
189 protected:
190 DataChannel(DataChannelProviderInterface* client,
191 cricket::DataChannelType dct,
192 const std::string& label);
193 virtual ~DataChannel();
194
195 private:
196 // A packet queue which tracks the total queued bytes. Queued packets are
197 // owned by this class.
198 class PacketQueue {
199 public:
200 PacketQueue();
201 ~PacketQueue();
202
203 size_t byte_count() const {
204 return byte_count_;
205 }
206
207 bool Empty() const;
208
209 DataBuffer* Front();
210
211 void Pop();
212
213 void Push(DataBuffer* packet);
214
215 void Clear();
216
217 void Swap(PacketQueue* other);
218
219 private:
220 std::deque<DataBuffer*> packets_;
221 size_t byte_count_;
222 };
223
224 // The OPEN(_ACK) signaling state.
225 enum HandshakeState {
226 kHandshakeInit,
227 kHandshakeShouldSendOpen,
228 kHandshakeShouldSendAck,
229 kHandshakeWaitingForAck,
230 kHandshakeReady
231 };
232
233 bool Init(const InternalDataChannelInit& config);
234 void DoClose();
235 void UpdateState();
236 void SetState(DataState state);
237 void DisconnectFromProvider();
238
239 void DeliverQueuedReceivedData();
240
241 void SendQueuedDataMessages();
242 bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked);
243 bool QueueSendDataMessage(const DataBuffer& buffer);
244
245 void SendQueuedControlMessages();
246 void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer);
247 bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer);
248
249 std::string label_;
250 InternalDataChannelInit config_;
251 DataChannelObserver* observer_;
252 DataState state_;
253 uint32_t messages_sent_;
254 uint64_t bytes_sent_;
255 uint32_t messages_received_;
256 uint64_t bytes_received_;
257 cricket::DataChannelType data_channel_type_;
258 DataChannelProviderInterface* provider_;
259 HandshakeState handshake_state_;
260 bool connected_to_provider_;
261 bool send_ssrc_set_;
262 bool receive_ssrc_set_;
263 bool writable_;
264 uint32_t send_ssrc_;
265 uint32_t receive_ssrc_;
266 // Control messages that always have to get sent out before any queued
267 // data.
268 PacketQueue queued_control_data_;
269 PacketQueue queued_received_data_;
270 PacketQueue queued_send_data_;
271};
272
273// Define proxy for DataChannelInterface.
274BEGIN_SIGNALING_PROXY_MAP(DataChannel)
275 PROXY_SIGNALING_THREAD_DESTRUCTOR()
276 PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*)
277 PROXY_METHOD0(void, UnregisterObserver)
278 PROXY_CONSTMETHOD0(std::string, label)
279 PROXY_CONSTMETHOD0(bool, reliable)
280 PROXY_CONSTMETHOD0(bool, ordered)
281 PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime)
282 PROXY_CONSTMETHOD0(uint16_t, maxRetransmits)
283 PROXY_CONSTMETHOD0(std::string, protocol)
284 PROXY_CONSTMETHOD0(bool, negotiated)
285 PROXY_CONSTMETHOD0(int, id)
286 PROXY_CONSTMETHOD0(DataState, state)
287 PROXY_CONSTMETHOD0(uint32_t, messages_sent)
288 PROXY_CONSTMETHOD0(uint64_t, bytes_sent)
289 PROXY_CONSTMETHOD0(uint32_t, messages_received)
290 PROXY_CONSTMETHOD0(uint64_t, bytes_received)
291 PROXY_CONSTMETHOD0(uint64_t, buffered_amount)
292 PROXY_METHOD0(void, Close)
293 PROXY_METHOD1(bool, Send, const DataBuffer&)
294END_PROXY_MAP()
295
296} // namespace webrtc
297
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200298#endif // PC_DATACHANNEL_H_