blob: 19f95df44484ae94fa0aa875f8ce3f0c72937993 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
Henrik Kjellander15583c12016-02-10 10:53:12 +010011#ifndef WEBRTC_API_DATACHANNEL_H_
12#define WEBRTC_API_DATACHANNEL_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +000014#include <deque>
deadbeefab9b2d12015-10-14 11:33:11 -070015#include <set>
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000016#include <string>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000017
Henrik Kjellander15583c12016-02-10 10:53:12 +010018#include "webrtc/api/datachannelinterface.h"
19#include "webrtc/api/proxy.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000020#include "webrtc/base/messagehandler.h"
21#include "webrtc/base/scoped_ref_ptr.h"
22#include "webrtc/base/sigslot.h"
kjellandera96e2d72016-02-04 23:52:28 -080023#include "webrtc/media/base/mediachannel.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010024#include "webrtc/pc/channel.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025
26namespace webrtc {
27
wu@webrtc.org78187522013-10-07 23:32:02 +000028class DataChannel;
29
30class DataChannelProviderInterface {
31 public:
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000032 // Sends the data to the transport.
wu@webrtc.org78187522013-10-07 23:32:02 +000033 virtual bool SendData(const cricket::SendDataParams& params,
jbaucheec21bd2016-03-20 06:15:43 -070034 const rtc::CopyOnWriteBuffer& payload,
wu@webrtc.org78187522013-10-07 23:32:02 +000035 cricket::SendDataResult* result) = 0;
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000036 // Connects to the transport signals.
wu@webrtc.org78187522013-10-07 23:32:02 +000037 virtual bool ConnectDataChannel(DataChannel* data_channel) = 0;
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000038 // Disconnects from the transport signals.
wu@webrtc.org78187522013-10-07 23:32:02 +000039 virtual void DisconnectDataChannel(DataChannel* data_channel) = 0;
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000040 // Adds the data channel SID to the transport for SCTP.
bemasc@webrtc.org9b5467e2014-12-04 23:16:52 +000041 virtual void AddSctpDataStream(int sid) = 0;
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000042 // Removes the data channel SID from the transport for SCTP.
bemasc@webrtc.org9b5467e2014-12-04 23:16:52 +000043 virtual void RemoveSctpDataStream(int sid) = 0;
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +000044 // Returns true if the transport channel is ready to send data.
45 virtual bool ReadyToSendData() const = 0;
wu@webrtc.org78187522013-10-07 23:32:02 +000046
47 protected:
48 virtual ~DataChannelProviderInterface() {}
49};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000051struct 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
deadbeefab9b2d12015-10-14 11:33:11 -070070// 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
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092// DataChannel is a an implementation of the DataChannelInterface based on
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000093// 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096
97// DataChannel states:
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000098// kConnecting: The channel has been created the transport might not yet be
99// ready.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100// 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,
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000108 public sigslot::has_slots<>,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000109 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000111 static rtc::scoped_refptr<DataChannel> Create(
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000112 DataChannelProviderInterface* provider,
wu@webrtc.org78187522013-10-07 23:32:02 +0000113 cricket::DataChannelType dct,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114 const std::string& label,
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000115 const InternalDataChannelInit& config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116
117 virtual void RegisterObserver(DataChannelObserver* observer);
118 virtual void UnregisterObserver();
119
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000120 virtual std::string label() const { return label_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121 virtual bool reliable() const;
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000122 virtual bool ordered() const { return config_.ordered; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200123 virtual uint16_t maxRetransmitTime() const {
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000124 return config_.maxRetransmitTime;
125 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200126 virtual uint16_t maxRetransmits() const { return config_.maxRetransmits; }
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000127 virtual std::string protocol() const { return config_.protocol; }
128 virtual bool negotiated() const { return config_.negotiated; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 virtual int id() const { return config_.id; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200130 virtual uint64_t buffered_amount() const;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131 virtual void Close();
132 virtual DataState state() const { return state_; }
hbos84ffdee2016-10-12 14:14:39 -0700133 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_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 virtual bool Send(const DataBuffer& buffer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000139 // rtc::MessageHandler override.
140 virtual void OnMessage(rtc::Message* msg);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000141
wu@webrtc.org91053e72013-08-10 07:18:04 +0000142 // 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);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000146
deadbeef953c2ce2017-01-09 14:53:41 -0800147 // Slots for provider to connect signals to.
148 void OnDataReceived(const cricket::ReceiveDataParams& params,
jbaucheec21bd2016-03-20 06:15:43 -0700149 const rtc::CopyOnWriteBuffer& payload);
deadbeef953c2ce2017-01-09 14:53:41 -0800150 void OnStreamClosedRemotely(int sid);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000152 // The remote peer request that this channel should be closed.
153 void RemotePeerRequestClose();
154
155 // The following methods are for SCTP only.
156
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000157 // Sets the SCTP sid and adds to transport layer if not set yet. Should only
158 // be called once.
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000159 void SetSctpSid(int sid);
160 // Called when the transport channel is created.
deadbeefab9b2d12015-10-14 11:33:11 -0700161 // Only needs to be called for SCTP data channels.
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000162 void OnTransportChannelCreated();
deadbeefab9b2d12015-10-14 11:33:11 -0700163 // Called when the transport channel is destroyed.
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700164 // This method makes sure the DataChannel is disconnected and changes state
165 // to kClosed.
deadbeefab9b2d12015-10-14 11:33:11 -0700166 void OnTransportChannelDestroyed();
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000167
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.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200173 void SetSendSsrc(uint32_t send_ssrc);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000174 // Set the SSRC this channel should use to receive data from the
175 // underlying data engine.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200176 void SetReceiveSsrc(uint32_t receive_ssrc);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000177
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000178 cricket::DataChannelType data_channel_type() const {
179 return data_channel_type_;
180 }
181
hbos82ebe022016-11-14 01:41:09 -0800182 // Emitted when state transitions to kOpen.
183 sigslot::signal1<DataChannel*> SignalOpened;
deadbeefab9b2d12015-10-14 11:33:11 -0700184 // 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
wu@webrtc.org78187522013-10-07 23:32:02 +0000189 protected:
190 DataChannel(DataChannelProviderInterface* client,
191 cricket::DataChannelType dct,
192 const std::string& label);
193 virtual ~DataChannel();
194
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195 private:
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000196 // 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
Lally Singh5c6c6e02015-05-29 11:52:39 -0400224 // The OPEN(_ACK) signaling state.
225 enum HandshakeState {
226 kHandshakeInit,
227 kHandshakeShouldSendOpen,
228 kHandshakeShouldSendAck,
229 kHandshakeWaitingForAck,
230 kHandshakeReady
231 };
232
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000233 bool Init(const InternalDataChannelInit& config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 void DoClose();
235 void UpdateState();
236 void SetState(DataState state);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400237 void DisconnectFromProvider();
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000238
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000239 void DeliverQueuedReceivedData();
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000240
241 void SendQueuedDataMessages();
jiayl@webrtc.org6ca61902014-11-12 17:28:40 +0000242 bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked);
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000243 bool QueueSendDataMessage(const DataBuffer& buffer);
244
245 void SendQueuedControlMessages();
jbaucheec21bd2016-03-20 06:15:43 -0700246 void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer);
247 bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248
249 std::string label_;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000250 InternalDataChannelInit config_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 DataChannelObserver* observer_;
252 DataState state_;
hbos84ffdee2016-10-12 14:14:39 -0700253 uint32_t messages_sent_;
254 uint64_t bytes_sent_;
255 uint32_t messages_received_;
256 uint64_t bytes_received_;
henrika@webrtc.org44461fa2014-01-13 09:35:02 +0000257 cricket::DataChannelType data_channel_type_;
258 DataChannelProviderInterface* provider_;
Lally Singh5c6c6e02015-05-29 11:52:39 -0400259 HandshakeState handshake_state_;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000260 bool connected_to_provider_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 bool send_ssrc_set_;
henrika@webrtc.org44461fa2014-01-13 09:35:02 +0000262 bool receive_ssrc_set_;
Lally Singh5c6c6e02015-05-29 11:52:39 -0400263 bool writable_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200264 uint32_t send_ssrc_;
265 uint32_t receive_ssrc_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000266 // Control messages that always have to get sent out before any queued
267 // data.
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000268 PacketQueue queued_control_data_;
269 PacketQueue queued_received_data_;
270 PacketQueue queued_send_data_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271};
272
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273// Define proxy for DataChannelInterface.
nisse72c8d2b2016-04-15 03:49:07 -0700274BEGIN_SIGNALING_PROXY_MAP(DataChannel)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275 PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*)
276 PROXY_METHOD0(void, UnregisterObserver)
277 PROXY_CONSTMETHOD0(std::string, label)
278 PROXY_CONSTMETHOD0(bool, reliable)
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000279 PROXY_CONSTMETHOD0(bool, ordered)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200280 PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime)
281 PROXY_CONSTMETHOD0(uint16_t, maxRetransmits)
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000282 PROXY_CONSTMETHOD0(std::string, protocol)
283 PROXY_CONSTMETHOD0(bool, negotiated)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284 PROXY_CONSTMETHOD0(int, id)
285 PROXY_CONSTMETHOD0(DataState, state)
hbos84ffdee2016-10-12 14:14:39 -0700286 PROXY_CONSTMETHOD0(uint32_t, messages_sent)
287 PROXY_CONSTMETHOD0(uint64_t, bytes_sent)
288 PROXY_CONSTMETHOD0(uint32_t, messages_received)
289 PROXY_CONSTMETHOD0(uint64_t, bytes_received)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200290 PROXY_CONSTMETHOD0(uint64_t, buffered_amount)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000291 PROXY_METHOD0(void, Close)
292 PROXY_METHOD1(bool, Send, const DataBuffer&)
nisse72c8d2b2016-04-15 03:49:07 -0700293END_SIGNALING_PROXY()
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000294
295} // namespace webrtc
296
Henrik Kjellander15583c12016-02-10 10:53:12 +0100297#endif // WEBRTC_API_DATACHANNEL_H_