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