• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2012, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_APP_WEBRTC_DATACHANNEL_H_
29 #define TALK_APP_WEBRTC_DATACHANNEL_H_
30 
31 #include <deque>
32 #include <string>
33 
34 #include "talk/app/webrtc/datachannelinterface.h"
35 #include "talk/app/webrtc/proxy.h"
36 #include "talk/media/base/mediachannel.h"
37 #include "talk/session/media/channel.h"
38 #include "webrtc/base/messagehandler.h"
39 #include "webrtc/base/scoped_ref_ptr.h"
40 #include "webrtc/base/sigslot.h"
41 
42 namespace webrtc {
43 
44 class DataChannel;
45 
46 class DataChannelProviderInterface {
47  public:
48   // Sends the data to the transport.
49   virtual bool SendData(const cricket::SendDataParams& params,
50                         const rtc::Buffer& payload,
51                         cricket::SendDataResult* result) = 0;
52   // Connects to the transport signals.
53   virtual bool ConnectDataChannel(DataChannel* data_channel) = 0;
54   // Disconnects from the transport signals.
55   virtual void DisconnectDataChannel(DataChannel* data_channel) = 0;
56   // Adds the data channel SID to the transport for SCTP.
57   virtual void AddSctpDataStream(uint32 sid) = 0;
58   // Removes the data channel SID from the transport for SCTP.
59   virtual void RemoveSctpDataStream(uint32 sid) = 0;
60   // Returns true if the transport channel is ready to send data.
61   virtual bool ReadyToSendData() const = 0;
62 
63  protected:
~DataChannelProviderInterface()64   virtual ~DataChannelProviderInterface() {}
65 };
66 
67 struct InternalDataChannelInit : public DataChannelInit {
68   enum OpenHandshakeRole {
69     kOpener,
70     kAcker,
71     kNone
72   };
73   // The default role is kOpener because the default |negotiated| is false.
InternalDataChannelInitInternalDataChannelInit74   InternalDataChannelInit() : open_handshake_role(kOpener) {}
InternalDataChannelInitInternalDataChannelInit75   explicit InternalDataChannelInit(const DataChannelInit& base)
76       : DataChannelInit(base), open_handshake_role(kOpener) {
77     // If the channel is externally negotiated, do not send the OPEN message.
78     if (base.negotiated) {
79       open_handshake_role = kNone;
80     }
81   }
82 
83   OpenHandshakeRole open_handshake_role;
84 };
85 
86 // DataChannel is a an implementation of the DataChannelInterface based on
87 // libjingle's data engine. It provides an implementation of unreliable or
88 // reliabledata channels. Currently this class is specifically designed to use
89 // both RtpDataEngine and SctpDataEngine.
90 
91 // DataChannel states:
92 // kConnecting: The channel has been created the transport might not yet be
93 //              ready.
94 // kOpen: The channel have a local SSRC set by a call to UpdateSendSsrc
95 //        and a remote SSRC set by call to UpdateReceiveSsrc and the transport
96 //        has been writable once.
97 // kClosing: DataChannelInterface::Close has been called or UpdateReceiveSsrc
98 //           has been called with SSRC==0
99 // kClosed: Both UpdateReceiveSsrc and UpdateSendSsrc has been called with
100 //          SSRC==0.
101 class DataChannel : public DataChannelInterface,
102                     public sigslot::has_slots<>,
103                     public rtc::MessageHandler {
104  public:
105   static rtc::scoped_refptr<DataChannel> Create(
106       DataChannelProviderInterface* provider,
107       cricket::DataChannelType dct,
108       const std::string& label,
109       const InternalDataChannelInit& config);
110 
111   virtual void RegisterObserver(DataChannelObserver* observer);
112   virtual void UnregisterObserver();
113 
label()114   virtual std::string label() const { return label_; }
115   virtual bool reliable() const;
ordered()116   virtual bool ordered() const { return config_.ordered; }
maxRetransmitTime()117   virtual uint16 maxRetransmitTime() const {
118     return config_.maxRetransmitTime;
119   }
maxRetransmits()120   virtual uint16 maxRetransmits() const {
121     return config_.maxRetransmits;
122   }
protocol()123   virtual std::string protocol() const { return config_.protocol; }
negotiated()124   virtual bool negotiated() const { return config_.negotiated; }
id()125   virtual int id() const { return config_.id; }
126   virtual uint64 buffered_amount() const;
127   virtual void Close();
state()128   virtual DataState state() const { return state_; }
129   virtual bool Send(const DataBuffer& buffer);
130 
131   // rtc::MessageHandler override.
132   virtual void OnMessage(rtc::Message* msg);
133 
134   // Called if the underlying data engine is closing.
135   void OnDataEngineClose();
136 
137   // Called when the channel's ready to use.  That can happen when the
138   // underlying DataMediaChannel becomes ready, or when this channel is a new
139   // stream on an existing DataMediaChannel, and we've finished negotiation.
140   void OnChannelReady(bool writable);
141 
142   // Sigslots from cricket::DataChannel
143   void OnDataReceived(cricket::DataChannel* channel,
144                       const cricket::ReceiveDataParams& params,
145                       const rtc::Buffer& payload);
146 
147   // The remote peer request that this channel should be closed.
148   void RemotePeerRequestClose();
149 
150   // The following methods are for SCTP only.
151 
152   // Sets the SCTP sid and adds to transport layer if not set yet. Should only
153   // be called once.
154   void SetSctpSid(int sid);
155   // Called when the transport channel is created.
156   void OnTransportChannelCreated();
157 
158   // The following methods are for RTP only.
159 
160   // Set the SSRC this channel should use to send data on the
161   // underlying data engine. |send_ssrc| == 0 means that the channel is no
162   // longer part of the session negotiation.
163   void SetSendSsrc(uint32 send_ssrc);
164   // Set the SSRC this channel should use to receive data from the
165   // underlying data engine.
166   void SetReceiveSsrc(uint32 receive_ssrc);
167 
data_channel_type()168   cricket::DataChannelType data_channel_type() const {
169     return data_channel_type_;
170   }
171 
172  protected:
173   DataChannel(DataChannelProviderInterface* client,
174               cricket::DataChannelType dct,
175               const std::string& label);
176   virtual ~DataChannel();
177 
178  private:
179   // A packet queue which tracks the total queued bytes. Queued packets are
180   // owned by this class.
181   class PacketQueue {
182    public:
183     PacketQueue();
184     ~PacketQueue();
185 
byte_count()186     size_t byte_count() const {
187       return byte_count_;
188     }
189 
190     bool Empty() const;
191 
192     DataBuffer* Front();
193 
194     void Pop();
195 
196     void Push(DataBuffer* packet);
197 
198     void Clear();
199 
200     void Swap(PacketQueue* other);
201 
202    private:
203     std::deque<DataBuffer*> packets_;
204     size_t byte_count_;
205   };
206 
207   bool Init(const InternalDataChannelInit& config);
208   void DoClose();
209   void UpdateState();
210   void SetState(DataState state);
211   void DisconnectFromTransport();
212 
213   void DeliverQueuedReceivedData();
214 
215   void SendQueuedDataMessages();
216   bool SendDataMessage(const DataBuffer& buffer);
217   bool QueueSendDataMessage(const DataBuffer& buffer);
218 
219   void SendQueuedControlMessages();
220   void QueueControlMessage(const rtc::Buffer& buffer);
221   bool SendControlMessage(const rtc::Buffer& buffer);
222 
223   std::string label_;
224   InternalDataChannelInit config_;
225   DataChannelObserver* observer_;
226   DataState state_;
227   cricket::DataChannelType data_channel_type_;
228   DataChannelProviderInterface* provider_;
229   bool waiting_for_open_ack_;
230   bool was_ever_writable_;
231   bool connected_to_provider_;
232   bool send_ssrc_set_;
233   bool receive_ssrc_set_;
234   uint32 send_ssrc_;
235   uint32 receive_ssrc_;
236   // Control messages that always have to get sent out before any queued
237   // data.
238   PacketQueue queued_control_data_;
239   PacketQueue queued_received_data_;
240   PacketQueue queued_send_data_;
241 };
242 
243 class DataChannelFactory {
244  public:
245   virtual rtc::scoped_refptr<DataChannel> CreateDataChannel(
246       const std::string& label,
247       const InternalDataChannelInit* config) = 0;
248 
249  protected:
~DataChannelFactory()250   virtual ~DataChannelFactory() {}
251 };
252 
253 // Define proxy for DataChannelInterface.
254 BEGIN_PROXY_MAP(DataChannel)
255   PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*)
256   PROXY_METHOD0(void, UnregisterObserver)
257   PROXY_CONSTMETHOD0(std::string, label)
258   PROXY_CONSTMETHOD0(bool, reliable)
259   PROXY_CONSTMETHOD0(bool, ordered)
260   PROXY_CONSTMETHOD0(uint16, maxRetransmitTime)
261   PROXY_CONSTMETHOD0(uint16, maxRetransmits)
262   PROXY_CONSTMETHOD0(std::string, protocol)
263   PROXY_CONSTMETHOD0(bool, negotiated)
264   PROXY_CONSTMETHOD0(int, id)
265   PROXY_CONSTMETHOD0(DataState, state)
266   PROXY_CONSTMETHOD0(uint64, buffered_amount)
267   PROXY_METHOD0(void, Close)
268   PROXY_METHOD1(bool, Send, const DataBuffer&)
269 END_PROXY()
270 
271 }  // namespace webrtc
272 
273 #endif  // TALK_APP_WEBRTC_DATACHANNEL_H_
274