OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/api/datachannel.h" | 11 #include "webrtc/api/datachannel.h" |
12 | 12 |
13 #include <memory> | 13 #include <memory> |
14 #include <string> | 14 #include <string> |
15 | 15 |
16 #include "webrtc/api/sctputils.h" | 16 #include "webrtc/api/sctputils.h" |
| 17 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
18 #include "webrtc/base/refcount.h" | 19 #include "webrtc/base/refcount.h" |
19 #include "webrtc/media/sctp/sctptransportinternal.h" | 20 #include "webrtc/media/sctp/sctptransportinternal.h" |
20 | 21 |
21 namespace webrtc { | 22 namespace webrtc { |
22 | 23 |
23 static size_t kMaxQueuedReceivedDataBytes = 16 * 1024 * 1024; | 24 static size_t kMaxQueuedReceivedDataBytes = 16 * 1024 * 1024; |
24 static size_t kMaxQueuedSendDataBytes = 16 * 1024 * 1024; | 25 static size_t kMaxQueuedSendDataBytes = 16 * 1024 * 1024; |
25 | 26 |
26 enum { | 27 enum { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 // code accordingly. | 242 // code accordingly. |
242 if (buffer.size() == 0) { | 243 if (buffer.size() == 0) { |
243 return true; | 244 return true; |
244 } | 245 } |
245 | 246 |
246 // If the queue is non-empty, we're waiting for SignalReadyToSend, | 247 // If the queue is non-empty, we're waiting for SignalReadyToSend, |
247 // so just add to the end of the queue and keep waiting. | 248 // so just add to the end of the queue and keep waiting. |
248 if (!queued_send_data_.Empty()) { | 249 if (!queued_send_data_.Empty()) { |
249 // Only SCTP DataChannel queues the outgoing data when the transport is | 250 // Only SCTP DataChannel queues the outgoing data when the transport is |
250 // blocked. | 251 // blocked. |
251 ASSERT(data_channel_type_ == cricket::DCT_SCTP); | 252 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); |
252 if (!QueueSendDataMessage(buffer)) { | 253 if (!QueueSendDataMessage(buffer)) { |
253 Close(); | 254 Close(); |
254 } | 255 } |
255 return true; | 256 return true; |
256 } | 257 } |
257 | 258 |
258 bool success = SendDataMessage(buffer, true); | 259 bool success = SendDataMessage(buffer, true); |
259 if (data_channel_type_ == cricket::DCT_RTP) { | 260 if (data_channel_type_ == cricket::DCT_RTP) { |
260 return success; | 261 return success; |
261 } | 262 } |
262 | 263 |
263 // Always return true for SCTP DataChannel per the spec. | 264 // Always return true for SCTP DataChannel per the spec. |
264 return true; | 265 return true; |
265 } | 266 } |
266 | 267 |
267 void DataChannel::SetReceiveSsrc(uint32_t receive_ssrc) { | 268 void DataChannel::SetReceiveSsrc(uint32_t receive_ssrc) { |
268 ASSERT(data_channel_type_ == cricket::DCT_RTP); | 269 RTC_DCHECK(data_channel_type_ == cricket::DCT_RTP); |
269 | 270 |
270 if (receive_ssrc_set_) { | 271 if (receive_ssrc_set_) { |
271 return; | 272 return; |
272 } | 273 } |
273 receive_ssrc_ = receive_ssrc; | 274 receive_ssrc_ = receive_ssrc; |
274 receive_ssrc_set_ = true; | 275 receive_ssrc_set_ = true; |
275 UpdateState(); | 276 UpdateState(); |
276 } | 277 } |
277 | 278 |
278 // The remote peer request that this channel shall be closed. | 279 // The remote peer request that this channel shall be closed. |
279 void DataChannel::RemotePeerRequestClose() { | 280 void DataChannel::RemotePeerRequestClose() { |
280 DoClose(); | 281 DoClose(); |
281 } | 282 } |
282 | 283 |
283 void DataChannel::SetSctpSid(int sid) { | 284 void DataChannel::SetSctpSid(int sid) { |
284 ASSERT(config_.id < 0 && sid >= 0 && data_channel_type_ == cricket::DCT_SCTP); | 285 RTC_DCHECK(config_.id < 0 && sid >= 0 && |
| 286 data_channel_type_ == cricket::DCT_SCTP); |
285 if (config_.id == sid) { | 287 if (config_.id == sid) { |
286 return; | 288 return; |
287 } | 289 } |
288 | 290 |
289 config_.id = sid; | 291 config_.id = sid; |
290 provider_->AddSctpDataStream(sid); | 292 provider_->AddSctpDataStream(sid); |
291 } | 293 } |
292 | 294 |
293 void DataChannel::OnTransportChannelCreated() { | 295 void DataChannel::OnTransportChannelCreated() { |
294 ASSERT(data_channel_type_ == cricket::DCT_SCTP); | 296 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); |
295 if (!connected_to_provider_) { | 297 if (!connected_to_provider_) { |
296 connected_to_provider_ = provider_->ConnectDataChannel(this); | 298 connected_to_provider_ = provider_->ConnectDataChannel(this); |
297 } | 299 } |
298 // The sid may have been unassigned when provider_->ConnectDataChannel was | 300 // The sid may have been unassigned when provider_->ConnectDataChannel was |
299 // done. So always add the streams even if connected_to_provider_ is true. | 301 // done. So always add the streams even if connected_to_provider_ is true. |
300 if (config_.id >= 0) { | 302 if (config_.id >= 0) { |
301 provider_->AddSctpDataStream(config_.id); | 303 provider_->AddSctpDataStream(config_.id); |
302 } | 304 } |
303 } | 305 } |
304 | 306 |
305 void DataChannel::OnTransportChannelDestroyed() { | 307 void DataChannel::OnTransportChannelDestroyed() { |
306 // This method needs to synchronously close the data channel, which means any | 308 // This method needs to synchronously close the data channel, which means any |
307 // queued data needs to be discarded. | 309 // queued data needs to be discarded. |
308 queued_send_data_.Clear(); | 310 queued_send_data_.Clear(); |
309 queued_control_data_.Clear(); | 311 queued_control_data_.Clear(); |
310 DoClose(); | 312 DoClose(); |
311 } | 313 } |
312 | 314 |
313 void DataChannel::SetSendSsrc(uint32_t send_ssrc) { | 315 void DataChannel::SetSendSsrc(uint32_t send_ssrc) { |
314 ASSERT(data_channel_type_ == cricket::DCT_RTP); | 316 RTC_DCHECK(data_channel_type_ == cricket::DCT_RTP); |
315 if (send_ssrc_set_) { | 317 if (send_ssrc_set_) { |
316 return; | 318 return; |
317 } | 319 } |
318 send_ssrc_ = send_ssrc; | 320 send_ssrc_ = send_ssrc; |
319 send_ssrc_set_ = true; | 321 send_ssrc_set_ = true; |
320 UpdateState(); | 322 UpdateState(); |
321 } | 323 } |
322 | 324 |
323 void DataChannel::OnMessage(rtc::Message* msg) { | 325 void DataChannel::OnMessage(rtc::Message* msg) { |
324 switch (msg->message_id) { | 326 switch (msg->message_id) { |
325 case MSG_CHANNELREADY: | 327 case MSG_CHANNELREADY: |
326 OnChannelReady(true); | 328 OnChannelReady(true); |
327 break; | 329 break; |
328 } | 330 } |
329 } | 331 } |
330 | 332 |
331 void DataChannel::OnDataReceived(const cricket::ReceiveDataParams& params, | 333 void DataChannel::OnDataReceived(const cricket::ReceiveDataParams& params, |
332 const rtc::CopyOnWriteBuffer& payload) { | 334 const rtc::CopyOnWriteBuffer& payload) { |
333 if (data_channel_type_ == cricket::DCT_RTP && params.ssrc != receive_ssrc_) { | 335 if (data_channel_type_ == cricket::DCT_RTP && params.ssrc != receive_ssrc_) { |
334 return; | 336 return; |
335 } | 337 } |
336 if (data_channel_type_ == cricket::DCT_SCTP && params.sid != config_.id) { | 338 if (data_channel_type_ == cricket::DCT_SCTP && params.sid != config_.id) { |
337 return; | 339 return; |
338 } | 340 } |
339 | 341 |
340 if (params.type == cricket::DMT_CONTROL) { | 342 if (params.type == cricket::DMT_CONTROL) { |
341 ASSERT(data_channel_type_ == cricket::DCT_SCTP); | 343 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); |
342 if (handshake_state_ != kHandshakeWaitingForAck) { | 344 if (handshake_state_ != kHandshakeWaitingForAck) { |
343 // Ignore it if we are not expecting an ACK message. | 345 // Ignore it if we are not expecting an ACK message. |
344 LOG(LS_WARNING) << "DataChannel received unexpected CONTROL message, " | 346 LOG(LS_WARNING) << "DataChannel received unexpected CONTROL message, " |
345 << "sid = " << params.sid; | 347 << "sid = " << params.sid; |
346 return; | 348 return; |
347 } | 349 } |
348 if (ParseDataChannelOpenAckMessage(payload)) { | 350 if (ParseDataChannelOpenAckMessage(payload)) { |
349 // We can send unordered as soon as we receive the ACK message. | 351 // We can send unordered as soon as we receive the ACK message. |
350 handshake_state_ = kHandshakeReady; | 352 handshake_state_ = kHandshakeReady; |
351 LOG(LS_INFO) << "DataChannel received OPEN_ACK message, sid = " | 353 LOG(LS_INFO) << "DataChannel received OPEN_ACK message, sid = " |
352 << params.sid; | 354 << params.sid; |
353 } else { | 355 } else { |
354 LOG(LS_WARNING) << "DataChannel failed to parse OPEN_ACK message, sid = " | 356 LOG(LS_WARNING) << "DataChannel failed to parse OPEN_ACK message, sid = " |
355 << params.sid; | 357 << params.sid; |
356 } | 358 } |
357 return; | 359 return; |
358 } | 360 } |
359 | 361 |
360 ASSERT(params.type == cricket::DMT_BINARY || | 362 RTC_DCHECK(params.type == cricket::DMT_BINARY || |
361 params.type == cricket::DMT_TEXT); | 363 params.type == cricket::DMT_TEXT); |
362 | 364 |
363 LOG(LS_VERBOSE) << "DataChannel received DATA message, sid = " << params.sid; | 365 LOG(LS_VERBOSE) << "DataChannel received DATA message, sid = " << params.sid; |
364 // We can send unordered as soon as we receive any DATA message since the | 366 // We can send unordered as soon as we receive any DATA message since the |
365 // remote side must have received the OPEN (and old clients do not send | 367 // remote side must have received the OPEN (and old clients do not send |
366 // OPEN_ACK). | 368 // OPEN_ACK). |
367 if (handshake_state_ == kHandshakeWaitingForAck) { | 369 if (handshake_state_ == kHandshakeWaitingForAck) { |
368 handshake_state_ = kHandshakeReady; | 370 handshake_state_ = kHandshakeReady; |
369 } | 371 } |
370 | 372 |
371 bool binary = (params.type == cricket::DMT_BINARY); | 373 bool binary = (params.type == cricket::DMT_BINARY); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 observer_->OnMessage(*buffer); | 512 observer_->OnMessage(*buffer); |
511 queued_received_data_.Pop(); | 513 queued_received_data_.Pop(); |
512 } | 514 } |
513 } | 515 } |
514 | 516 |
515 void DataChannel::SendQueuedDataMessages() { | 517 void DataChannel::SendQueuedDataMessages() { |
516 if (queued_send_data_.Empty()) { | 518 if (queued_send_data_.Empty()) { |
517 return; | 519 return; |
518 } | 520 } |
519 | 521 |
520 ASSERT(state_ == kOpen || state_ == kClosing); | 522 RTC_DCHECK(state_ == kOpen || state_ == kClosing); |
521 | 523 |
522 uint64_t start_buffered_amount = buffered_amount(); | 524 uint64_t start_buffered_amount = buffered_amount(); |
523 while (!queued_send_data_.Empty()) { | 525 while (!queued_send_data_.Empty()) { |
524 DataBuffer* buffer = queued_send_data_.Front(); | 526 DataBuffer* buffer = queued_send_data_.Front(); |
525 if (!SendDataMessage(*buffer, false)) { | 527 if (!SendDataMessage(*buffer, false)) { |
526 // Leave the message in the queue if sending is aborted. | 528 // Leave the message in the queue if sending is aborted. |
527 break; | 529 break; |
528 } | 530 } |
529 queued_send_data_.Pop(); | 531 queued_send_data_.Pop(); |
530 delete buffer; | 532 delete buffer; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 } | 611 } |
610 } | 612 } |
611 | 613 |
612 void DataChannel::QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer) { | 614 void DataChannel::QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer) { |
613 queued_control_data_.Push(new DataBuffer(buffer, true)); | 615 queued_control_data_.Push(new DataBuffer(buffer, true)); |
614 } | 616 } |
615 | 617 |
616 bool DataChannel::SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) { | 618 bool DataChannel::SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) { |
617 bool is_open_message = handshake_state_ == kHandshakeShouldSendOpen; | 619 bool is_open_message = handshake_state_ == kHandshakeShouldSendOpen; |
618 | 620 |
619 ASSERT(data_channel_type_ == cricket::DCT_SCTP && | 621 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP && writable_ && |
620 writable_ && | 622 config_.id >= 0 && (!is_open_message || !config_.negotiated)); |
621 config_.id >= 0 && | |
622 (!is_open_message || !config_.negotiated)); | |
623 | 623 |
624 cricket::SendDataParams send_params; | 624 cricket::SendDataParams send_params; |
625 send_params.sid = config_.id; | 625 send_params.sid = config_.id; |
626 // Send data as ordered before we receive any message from the remote peer to | 626 // Send data as ordered before we receive any message from the remote peer to |
627 // make sure the remote peer will not receive any data before it receives the | 627 // make sure the remote peer will not receive any data before it receives the |
628 // OPEN message. | 628 // OPEN message. |
629 send_params.ordered = config_.ordered || is_open_message; | 629 send_params.ordered = config_.ordered || is_open_message; |
630 send_params.type = cricket::DMT_CONTROL; | 630 send_params.type = cricket::DMT_CONTROL; |
631 | 631 |
632 cricket::SendDataResult send_result = cricket::SDR_SUCCESS; | 632 cricket::SendDataResult send_result = cricket::SDR_SUCCESS; |
(...skipping 10 matching lines...) Expand all Loading... |
643 QueueControlMessage(buffer); | 643 QueueControlMessage(buffer); |
644 } else { | 644 } else { |
645 LOG(LS_ERROR) << "Closing the DataChannel due to a failure to send" | 645 LOG(LS_ERROR) << "Closing the DataChannel due to a failure to send" |
646 << " the CONTROL message, send_result = " << send_result; | 646 << " the CONTROL message, send_result = " << send_result; |
647 Close(); | 647 Close(); |
648 } | 648 } |
649 return retval; | 649 return retval; |
650 } | 650 } |
651 | 651 |
652 } // namespace webrtc | 652 } // namespace webrtc |
OLD | NEW |