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 <string> 32 #include <queue> 33 34 #include "talk/app/webrtc/datachannelinterface.h" 35 #include "talk/app/webrtc/proxy.h" 36 #include "talk/base/messagehandler.h" 37 #include "talk/base/scoped_ref_ptr.h" 38 #include "talk/base/sigslot.h" 39 #include "talk/media/base/mediachannel.h" 40 #include "talk/session/media/channel.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 talk_base::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: 64 virtual ~DataChannelProviderInterface() {} 65 }; 66 67 // DataChannel is a an implementation of the DataChannelInterface based on 68 // libjingle's data engine. It provides an implementation of unreliable or 69 // reliabledata channels. Currently this class is specifically designed to use 70 // both RtpDataEngine and SctpDataEngine. 71 72 // DataChannel states: 73 // kConnecting: The channel has been created the transport might not yet be 74 // ready. 75 // kOpen: The channel have a local SSRC set by a call to UpdateSendSsrc 76 // and a remote SSRC set by call to UpdateReceiveSsrc and the transport 77 // has been writable once. 78 // kClosing: DataChannelInterface::Close has been called or UpdateReceiveSsrc 79 // has been called with SSRC==0 80 // kClosed: Both UpdateReceiveSsrc and UpdateSendSsrc has been called with 81 // SSRC==0. 82 class DataChannel : public DataChannelInterface, 83 public sigslot::has_slots<>, 84 public talk_base::MessageHandler { 85 public: 86 static talk_base::scoped_refptr<DataChannel> Create( 87 DataChannelProviderInterface* provider, 88 cricket::DataChannelType dct, 89 const std::string& label, 90 const DataChannelInit* config); 91 92 virtual void RegisterObserver(DataChannelObserver* observer); 93 virtual void UnregisterObserver(); 94 95 virtual std::string label() const { return label_; } 96 virtual bool reliable() const; 97 virtual bool ordered() const { return config_.ordered; } 98 virtual uint16 maxRetransmitTime() const { 99 return config_.maxRetransmitTime; 100 } 101 virtual uint16 maxRetransmits() const { 102 return config_.maxRetransmits; 103 } 104 virtual std::string protocol() const { return config_.protocol; } 105 virtual bool negotiated() const { return config_.negotiated; } 106 virtual int id() const { return config_.id; } 107 virtual uint64 buffered_amount() const; 108 virtual void Close(); 109 virtual DataState state() const { return state_; } 110 virtual bool Send(const DataBuffer& buffer); 111 112 // talk_base::MessageHandler override. 113 virtual void OnMessage(talk_base::Message* msg); 114 115 // Called if the underlying data engine is closing. 116 void OnDataEngineClose(); 117 118 // Called when the channel's ready to use. That can happen when the 119 // underlying DataMediaChannel becomes ready, or when this channel is a new 120 // stream on an existing DataMediaChannel, and we've finished negotiation. 121 void OnChannelReady(bool writable); 122 123 // Sigslots from cricket::DataChannel 124 void OnDataReceived(cricket::DataChannel* channel, 125 const cricket::ReceiveDataParams& params, 126 const talk_base::Buffer& payload); 127 128 // The remote peer request that this channel should be closed. 129 void RemotePeerRequestClose(); 130 131 // The following methods are for SCTP only. 132 133 // Sets the SCTP sid and adds to transport layer if not set yet. 134 void SetSctpSid(int sid); 135 // Called when the transport channel is created. 136 void OnTransportChannelCreated(); 137 138 // The following methods are for RTP only. 139 140 // Set the SSRC this channel should use to send data on the 141 // underlying data engine. |send_ssrc| == 0 means that the channel is no 142 // longer part of the session negotiation. 143 void SetSendSsrc(uint32 send_ssrc); 144 // Set the SSRC this channel should use to receive data from the 145 // underlying data engine. 146 void SetReceiveSsrc(uint32 receive_ssrc); 147 148 cricket::DataChannelType data_channel_type() const { 149 return data_channel_type_; 150 } 151 152 protected: 153 DataChannel(DataChannelProviderInterface* client, 154 cricket::DataChannelType dct, 155 const std::string& label); 156 virtual ~DataChannel(); 157 158 private: 159 bool Init(const DataChannelInit* config); 160 void DoClose(); 161 void UpdateState(); 162 void SetState(DataState state); 163 void DisconnectFromTransport(); 164 void DeliverQueuedControlData(); 165 void QueueControl(const talk_base::Buffer* buffer); 166 void ClearQueuedControlData(); 167 void DeliverQueuedReceivedData(); 168 void ClearQueuedReceivedData(); 169 void DeliverQueuedSendData(); 170 void ClearQueuedSendData(); 171 bool InternalSendWithoutQueueing(const DataBuffer& buffer, 172 cricket::SendDataResult* send_result); 173 bool QueueSendData(const DataBuffer& buffer); 174 bool SendOpenMessage(const talk_base::Buffer* buffer); 175 176 177 std::string label_; 178 DataChannelInit config_; 179 DataChannelObserver* observer_; 180 DataState state_; 181 bool was_ever_writable_; 182 bool connected_to_provider_; 183 cricket::DataChannelType data_channel_type_; 184 DataChannelProviderInterface* provider_; 185 bool send_ssrc_set_; 186 uint32 send_ssrc_; 187 bool receive_ssrc_set_; 188 uint32 receive_ssrc_; 189 // Control messages that always have to get sent out before any queued 190 // data. 191 std::queue<const talk_base::Buffer*> queued_control_data_; 192 std::queue<DataBuffer*> queued_received_data_; 193 std::deque<DataBuffer*> queued_send_data_; 194 }; 195 196 class DataChannelFactory { 197 public: 198 virtual talk_base::scoped_refptr<DataChannel> CreateDataChannel( 199 const std::string& label, 200 const DataChannelInit* config) = 0; 201 202 protected: 203 virtual ~DataChannelFactory() {} 204 }; 205 206 // Define proxy for DataChannelInterface. 207 BEGIN_PROXY_MAP(DataChannel) 208 PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*) 209 PROXY_METHOD0(void, UnregisterObserver) 210 PROXY_CONSTMETHOD0(std::string, label) 211 PROXY_CONSTMETHOD0(bool, reliable) 212 PROXY_CONSTMETHOD0(bool, ordered) 213 PROXY_CONSTMETHOD0(uint16, maxRetransmitTime) 214 PROXY_CONSTMETHOD0(uint16, maxRetransmits) 215 PROXY_CONSTMETHOD0(std::string, protocol) 216 PROXY_CONSTMETHOD0(bool, negotiated) 217 PROXY_CONSTMETHOD0(int, id) 218 PROXY_CONSTMETHOD0(DataState, state) 219 PROXY_CONSTMETHOD0(uint64, buffered_amount) 220 PROXY_METHOD0(void, Close) 221 PROXY_METHOD1(bool, Send, const DataBuffer&) 222 END_PROXY() 223 224 } // namespace webrtc 225 226 #endif // TALK_APP_WEBRTC_DATACHANNEL_H_ 227