OLD | NEW |
| (Empty) |
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/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 #include "webrtc/media/base/mediachannel.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_ | |
OLD | NEW |