blob: 714e6e397e4448d1899666842116a970a84af122 [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_; }
133 virtual bool Send(const DataBuffer& buffer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000135 // rtc::MessageHandler override.
136 virtual void OnMessage(rtc::Message* msg);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000137
wu@webrtc.org91053e72013-08-10 07:18:04 +0000138 // Called when the channel's ready to use. That can happen when the
139 // underlying DataMediaChannel becomes ready, or when this channel is a new
140 // stream on an existing DataMediaChannel, and we've finished negotiation.
141 void OnChannelReady(bool writable);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142
143 // Sigslots from cricket::DataChannel
144 void OnDataReceived(cricket::DataChannel* channel,
145 const cricket::ReceiveDataParams& params,
jbaucheec21bd2016-03-20 06:15:43 -0700146 const rtc::CopyOnWriteBuffer& payload);
deadbeefab9b2d12015-10-14 11:33:11 -0700147 void OnStreamClosedRemotely(uint32_t sid);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000149 // The remote peer request that this channel should be closed.
150 void RemotePeerRequestClose();
151
152 // The following methods are for SCTP only.
153
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000154 // Sets the SCTP sid and adds to transport layer if not set yet. Should only
155 // be called once.
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000156 void SetSctpSid(int sid);
157 // Called when the transport channel is created.
deadbeefab9b2d12015-10-14 11:33:11 -0700158 // Only needs to be called for SCTP data channels.
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000159 void OnTransportChannelCreated();
deadbeefab9b2d12015-10-14 11:33:11 -0700160 // Called when the transport channel is destroyed.
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700161 // This method makes sure the DataChannel is disconnected and changes state
162 // to kClosed.
deadbeefab9b2d12015-10-14 11:33:11 -0700163 void OnTransportChannelDestroyed();
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000164
165 // The following methods are for RTP only.
166
167 // Set the SSRC this channel should use to send data on the
168 // underlying data engine. |send_ssrc| == 0 means that the channel is no
169 // longer part of the session negotiation.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200170 void SetSendSsrc(uint32_t send_ssrc);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000171 // Set the SSRC this channel should use to receive data from the
172 // underlying data engine.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200173 void SetReceiveSsrc(uint32_t receive_ssrc);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000174
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000175 cricket::DataChannelType data_channel_type() const {
176 return data_channel_type_;
177 }
178
deadbeefab9b2d12015-10-14 11:33:11 -0700179 // Emitted when state transitions to kClosed.
180 // In the case of SCTP channels, this signal can be used to tell when the
181 // channel's sid is free.
182 sigslot::signal1<DataChannel*> SignalClosed;
183
wu@webrtc.org78187522013-10-07 23:32:02 +0000184 protected:
185 DataChannel(DataChannelProviderInterface* client,
186 cricket::DataChannelType dct,
187 const std::string& label);
188 virtual ~DataChannel();
189
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 private:
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000191 // A packet queue which tracks the total queued bytes. Queued packets are
192 // owned by this class.
193 class PacketQueue {
194 public:
195 PacketQueue();
196 ~PacketQueue();
197
198 size_t byte_count() const {
199 return byte_count_;
200 }
201
202 bool Empty() const;
203
204 DataBuffer* Front();
205
206 void Pop();
207
208 void Push(DataBuffer* packet);
209
210 void Clear();
211
212 void Swap(PacketQueue* other);
213
214 private:
215 std::deque<DataBuffer*> packets_;
216 size_t byte_count_;
217 };
218
Lally Singh5c6c6e02015-05-29 11:52:39 -0400219 // The OPEN(_ACK) signaling state.
220 enum HandshakeState {
221 kHandshakeInit,
222 kHandshakeShouldSendOpen,
223 kHandshakeShouldSendAck,
224 kHandshakeWaitingForAck,
225 kHandshakeReady
226 };
227
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000228 bool Init(const InternalDataChannelInit& config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 void DoClose();
230 void UpdateState();
231 void SetState(DataState state);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400232 void DisconnectFromProvider();
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000233
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000234 void DeliverQueuedReceivedData();
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000235
236 void SendQueuedDataMessages();
jiayl@webrtc.org6ca61902014-11-12 17:28:40 +0000237 bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked);
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000238 bool QueueSendDataMessage(const DataBuffer& buffer);
239
240 void SendQueuedControlMessages();
jbaucheec21bd2016-03-20 06:15:43 -0700241 void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer);
242 bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243
244 std::string label_;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000245 InternalDataChannelInit config_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 DataChannelObserver* observer_;
247 DataState state_;
henrika@webrtc.org44461fa2014-01-13 09:35:02 +0000248 cricket::DataChannelType data_channel_type_;
249 DataChannelProviderInterface* provider_;
Lally Singh5c6c6e02015-05-29 11:52:39 -0400250 HandshakeState handshake_state_;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000251 bool connected_to_provider_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 bool send_ssrc_set_;
henrika@webrtc.org44461fa2014-01-13 09:35:02 +0000253 bool receive_ssrc_set_;
Lally Singh5c6c6e02015-05-29 11:52:39 -0400254 bool writable_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200255 uint32_t send_ssrc_;
256 uint32_t receive_ssrc_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000257 // Control messages that always have to get sent out before any queued
258 // data.
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000259 PacketQueue queued_control_data_;
260 PacketQueue queued_received_data_;
261 PacketQueue queued_send_data_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262};
263
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000264// Define proxy for DataChannelInterface.
nisse72c8d2b2016-04-15 03:49:07 -0700265BEGIN_SIGNALING_PROXY_MAP(DataChannel)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266 PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*)
267 PROXY_METHOD0(void, UnregisterObserver)
268 PROXY_CONSTMETHOD0(std::string, label)
269 PROXY_CONSTMETHOD0(bool, reliable)
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000270 PROXY_CONSTMETHOD0(bool, ordered)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200271 PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime)
272 PROXY_CONSTMETHOD0(uint16_t, maxRetransmits)
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000273 PROXY_CONSTMETHOD0(std::string, protocol)
274 PROXY_CONSTMETHOD0(bool, negotiated)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275 PROXY_CONSTMETHOD0(int, id)
276 PROXY_CONSTMETHOD0(DataState, state)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200277 PROXY_CONSTMETHOD0(uint64_t, buffered_amount)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 PROXY_METHOD0(void, Close)
279 PROXY_METHOD1(bool, Send, const DataBuffer&)
nisse72c8d2b2016-04-15 03:49:07 -0700280END_SIGNALING_PROXY()
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281
282} // namespace webrtc
283
Henrik Kjellander15583c12016-02-10 10:53:12 +0100284#endif // WEBRTC_API_DATACHANNEL_H_