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