| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 163 |
| 164 template <class Codec, class Options> | 164 template <class Codec, class Options> |
| 165 void RtpSendParametersFromMediaDescription( | 165 void RtpSendParametersFromMediaDescription( |
| 166 const MediaContentDescriptionImpl<Codec>* desc, | 166 const MediaContentDescriptionImpl<Codec>* desc, |
| 167 RtpSendParameters<Codec, Options>* send_params) { | 167 RtpSendParameters<Codec, Options>* send_params) { |
| 168 RtpParametersFromMediaDescription(desc, send_params); | 168 RtpParametersFromMediaDescription(desc, send_params); |
| 169 send_params->max_bandwidth_bps = desc->bandwidth(); | 169 send_params->max_bandwidth_bps = desc->bandwidth(); |
| 170 } | 170 } |
| 171 | 171 |
| 172 BaseChannel::BaseChannel(rtc::Thread* thread, | 172 BaseChannel::BaseChannel(rtc::Thread* thread, |
| 173 MediaChannel* media_channel, BaseSession* session, | 173 MediaChannel* media_channel, |
| 174 const std::string& content_name, bool rtcp) | 174 TransportController* transport_controller, |
| 175 const std::string& content_name, |
| 176 bool rtcp) |
| 175 : worker_thread_(thread), | 177 : worker_thread_(thread), |
| 176 session_(session), | 178 transport_controller_(transport_controller), |
| 177 media_channel_(media_channel), | 179 media_channel_(media_channel), |
| 178 content_name_(content_name), | 180 content_name_(content_name), |
| 179 rtcp_(rtcp), | 181 rtcp_transport_enabled_(rtcp), |
| 180 transport_channel_(NULL), | 182 transport_channel_(nullptr), |
| 181 rtcp_transport_channel_(NULL), | 183 rtcp_transport_channel_(nullptr), |
| 182 enabled_(false), | 184 enabled_(false), |
| 183 writable_(false), | 185 writable_(false), |
| 184 rtp_ready_to_send_(false), | 186 rtp_ready_to_send_(false), |
| 185 rtcp_ready_to_send_(false), | 187 rtcp_ready_to_send_(false), |
| 186 was_ever_writable_(false), | 188 was_ever_writable_(false), |
| 187 local_content_direction_(MD_INACTIVE), | 189 local_content_direction_(MD_INACTIVE), |
| 188 remote_content_direction_(MD_INACTIVE), | 190 remote_content_direction_(MD_INACTIVE), |
| 189 has_received_packet_(false), | 191 has_received_packet_(false), |
| 190 dtls_keyed_(false), | 192 dtls_keyed_(false), |
| 191 secure_required_(false), | 193 secure_required_(false), |
| 192 rtp_abs_sendtime_extn_id_(-1) { | 194 rtp_abs_sendtime_extn_id_(-1) { |
| 193 ASSERT(worker_thread_ == rtc::Thread::Current()); | 195 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 194 LOG(LS_INFO) << "Created channel for " << content_name; | 196 LOG(LS_INFO) << "Created channel for " << content_name; |
| 195 } | 197 } |
| 196 | 198 |
| 197 BaseChannel::~BaseChannel() { | 199 BaseChannel::~BaseChannel() { |
| 198 ASSERT(worker_thread_ == rtc::Thread::Current()); | 200 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 199 Deinit(); | 201 Deinit(); |
| 200 StopConnectionMonitor(); | 202 StopConnectionMonitor(); |
| 201 FlushRtcpMessages(); // Send any outstanding RTCP packets. | 203 FlushRtcpMessages(); // Send any outstanding RTCP packets. |
| 202 worker_thread_->Clear(this); // eats any outstanding messages or packets | 204 worker_thread_->Clear(this); // eats any outstanding messages or packets |
| 203 // We must destroy the media channel before the transport channel, otherwise | 205 // We must destroy the media channel before the transport channel, otherwise |
| 204 // the media channel may try to send on the dead transport channel. NULLing | 206 // the media channel may try to send on the dead transport channel. NULLing |
| 205 // is not an effective strategy since the sends will come on another thread. | 207 // is not an effective strategy since the sends will come on another thread. |
| 206 delete media_channel_; | 208 delete media_channel_; |
| 207 set_transport_channel(nullptr); | 209 // Note that we don't just call set_transport_channel(nullptr) because that |
| 208 set_rtcp_transport_channel(nullptr); | 210 // would call a pure virtual method which we can't do from a destructor. |
| 211 if (transport_channel_) { |
| 212 DisconnectFromTransportChannel(transport_channel_); |
| 213 transport_controller_->DestroyTransportChannel_w( |
| 214 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); |
| 215 } |
| 216 if (rtcp_transport_channel_) { |
| 217 DisconnectFromTransportChannel(rtcp_transport_channel_); |
| 218 transport_controller_->DestroyTransportChannel_w( |
| 219 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
| 220 } |
| 209 LOG(LS_INFO) << "Destroyed channel"; | 221 LOG(LS_INFO) << "Destroyed channel"; |
| 210 } | 222 } |
| 211 | 223 |
| 212 bool BaseChannel::Init() { | 224 bool BaseChannel::Init() { |
| 213 if (!SetTransportChannels(session(), rtcp())) { | 225 if (!SetTransport(content_name())) { |
| 214 return false; | 226 return false; |
| 215 } | 227 } |
| 216 | 228 |
| 217 if (!SetDtlsSrtpCiphers(transport_channel(), false)) { | 229 if (!SetDtlsSrtpCiphers(transport_channel(), false)) { |
| 218 return false; | 230 return false; |
| 219 } | 231 } |
| 220 if (rtcp() && !SetDtlsSrtpCiphers(rtcp_transport_channel(), true)) { | 232 if (rtcp_transport_enabled() && |
| 233 !SetDtlsSrtpCiphers(rtcp_transport_channel(), true)) { |
| 221 return false; | 234 return false; |
| 222 } | 235 } |
| 223 | 236 |
| 224 // Both RTP and RTCP channels are set, we can call SetInterface on | 237 // Both RTP and RTCP channels are set, we can call SetInterface on |
| 225 // media channel and it can set network options. | 238 // media channel and it can set network options. |
| 226 media_channel_->SetInterface(this); | 239 media_channel_->SetInterface(this); |
| 227 return true; | 240 return true; |
| 228 } | 241 } |
| 229 | 242 |
| 230 void BaseChannel::Deinit() { | 243 void BaseChannel::Deinit() { |
| 231 media_channel_->SetInterface(NULL); | 244 media_channel_->SetInterface(NULL); |
| 232 } | 245 } |
| 233 | 246 |
| 234 bool BaseChannel::SetTransportChannels(BaseSession* session, bool rtcp) { | 247 bool BaseChannel::SetTransport(const std::string& transport_name) { |
| 235 return worker_thread_->Invoke<bool>(Bind( | 248 return worker_thread_->Invoke<bool>( |
| 236 &BaseChannel::SetTransportChannels_w, this, session, rtcp)); | 249 Bind(&BaseChannel::SetTransport_w, this, transport_name)); |
| 237 } | 250 } |
| 238 | 251 |
| 239 bool BaseChannel::SetTransportChannels_w(BaseSession* session, bool rtcp) { | 252 bool BaseChannel::SetTransport_w(const std::string& transport_name) { |
| 240 ASSERT(worker_thread_ == rtc::Thread::Current()); | 253 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 241 | 254 |
| 242 set_transport_channel(session->CreateChannel( | 255 if (transport_name == transport_name_) { |
| 243 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP)); | 256 // Nothing to do if transport name isn't changing |
| 257 return true; |
| 258 } |
| 259 |
| 260 set_transport_channel(transport_controller_->CreateTransportChannel_w( |
| 261 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); |
| 244 if (!transport_channel()) { | 262 if (!transport_channel()) { |
| 245 return false; | 263 return false; |
| 246 } | 264 } |
| 247 if (rtcp) { | 265 if (rtcp_transport_enabled()) { |
| 248 set_rtcp_transport_channel(session->CreateChannel( | 266 LOG(LS_INFO) << "Create RTCP TransportChannel for " << content_name() |
| 249 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP)); | 267 << " on " << transport_name << " transport "; |
| 268 set_rtcp_transport_channel(transport_controller_->CreateTransportChannel_w( |
| 269 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP)); |
| 250 if (!rtcp_transport_channel()) { | 270 if (!rtcp_transport_channel()) { |
| 251 return false; | 271 return false; |
| 252 } | 272 } |
| 253 } else { | |
| 254 set_rtcp_transport_channel(nullptr); | |
| 255 } | 273 } |
| 256 | 274 |
| 275 transport_name_ = transport_name; |
| 257 return true; | 276 return true; |
| 258 } | 277 } |
| 259 | 278 |
| 260 void BaseChannel::set_transport_channel(TransportChannel* new_tc) { | 279 void BaseChannel::set_transport_channel(TransportChannel* new_tc) { |
| 261 ASSERT(worker_thread_ == rtc::Thread::Current()); | 280 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 262 | 281 |
| 263 TransportChannel* old_tc = transport_channel_; | 282 TransportChannel* old_tc = transport_channel_; |
| 264 | 283 if (!old_tc && !new_tc) { |
| 265 if (old_tc == new_tc) { | 284 // Nothing to do |
| 266 return; | 285 return; |
| 267 } | 286 } |
| 287 ASSERT(old_tc != new_tc); |
| 288 |
| 268 if (old_tc) { | 289 if (old_tc) { |
| 269 DisconnectFromTransportChannel(old_tc); | 290 DisconnectFromTransportChannel(old_tc); |
| 270 session()->DestroyChannel( | 291 transport_controller_->DestroyTransportChannel_w( |
| 271 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP); | 292 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); |
| 272 } | 293 } |
| 273 | 294 |
| 274 transport_channel_ = new_tc; | 295 transport_channel_ = new_tc; |
| 275 | 296 |
| 276 if (new_tc) { | 297 if (new_tc) { |
| 277 ConnectToTransportChannel(new_tc); | 298 ConnectToTransportChannel(new_tc); |
| 299 for (const auto& pair : socket_options_) { |
| 300 new_tc->SetOption(pair.first, pair.second); |
| 301 } |
| 278 } | 302 } |
| 303 |
| 304 // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| 305 // setting new channel |
| 306 UpdateWritableState_w(); |
| 307 SetReadyToSend(false, new_tc && new_tc->writable()); |
| 279 } | 308 } |
| 280 | 309 |
| 281 void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { | 310 void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { |
| 282 ASSERT(worker_thread_ == rtc::Thread::Current()); | 311 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 283 | 312 |
| 284 TransportChannel* old_tc = rtcp_transport_channel_; | 313 TransportChannel* old_tc = rtcp_transport_channel_; |
| 285 | 314 if (!old_tc && !new_tc) { |
| 286 if (old_tc == new_tc) { | 315 // Nothing to do |
| 287 return; | 316 return; |
| 288 } | 317 } |
| 318 ASSERT(old_tc != new_tc); |
| 319 |
| 289 if (old_tc) { | 320 if (old_tc) { |
| 290 DisconnectFromTransportChannel(old_tc); | 321 DisconnectFromTransportChannel(old_tc); |
| 291 session()->DestroyChannel( | 322 transport_controller_->DestroyTransportChannel_w( |
| 292 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP); | 323 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
| 293 } | 324 } |
| 294 | 325 |
| 295 rtcp_transport_channel_ = new_tc; | 326 rtcp_transport_channel_ = new_tc; |
| 296 | 327 |
| 297 if (new_tc) { | 328 if (new_tc) { |
| 298 ConnectToTransportChannel(new_tc); | 329 ConnectToTransportChannel(new_tc); |
| 330 for (const auto& pair : rtcp_socket_options_) { |
| 331 new_tc->SetOption(pair.first, pair.second); |
| 332 } |
| 299 } | 333 } |
| 334 |
| 335 // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| 336 // setting new channel |
| 337 UpdateWritableState_w(); |
| 338 SetReadyToSend(true, new_tc && new_tc->writable()); |
| 300 } | 339 } |
| 301 | 340 |
| 302 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { | 341 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
| 303 ASSERT(worker_thread_ == rtc::Thread::Current()); | 342 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 304 | 343 |
| 305 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 344 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
| 306 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); | 345 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
| 307 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | 346 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
| 308 } | 347 } |
| 309 | 348 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 rtc::DiffServCodePoint dscp) { | 439 rtc::DiffServCodePoint dscp) { |
| 401 return SendPacket(true, packet, dscp); | 440 return SendPacket(true, packet, dscp); |
| 402 } | 441 } |
| 403 | 442 |
| 404 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, | 443 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, |
| 405 int value) { | 444 int value) { |
| 406 TransportChannel* channel = NULL; | 445 TransportChannel* channel = NULL; |
| 407 switch (type) { | 446 switch (type) { |
| 408 case ST_RTP: | 447 case ST_RTP: |
| 409 channel = transport_channel_; | 448 channel = transport_channel_; |
| 449 socket_options_.push_back( |
| 450 std::pair<rtc::Socket::Option, int>(opt, value)); |
| 410 break; | 451 break; |
| 411 case ST_RTCP: | 452 case ST_RTCP: |
| 412 channel = rtcp_transport_channel_; | 453 channel = rtcp_transport_channel_; |
| 454 rtcp_socket_options_.push_back( |
| 455 std::pair<rtc::Socket::Option, int>(opt, value)); |
| 413 break; | 456 break; |
| 414 } | 457 } |
| 415 return channel ? channel->SetOption(opt, value) : -1; | 458 return channel ? channel->SetOption(opt, value) : -1; |
| 416 } | 459 } |
| 417 | 460 |
| 418 void BaseChannel::OnWritableState(TransportChannel* channel) { | 461 void BaseChannel::OnWritableState(TransportChannel* channel) { |
| 419 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 462 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| 420 if (transport_channel_->writable() | 463 UpdateWritableState_w(); |
| 421 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { | |
| 422 ChannelWritable_w(); | |
| 423 } else { | |
| 424 ChannelNotWritable_w(); | |
| 425 } | |
| 426 } | 464 } |
| 427 | 465 |
| 428 void BaseChannel::OnChannelRead(TransportChannel* channel, | 466 void BaseChannel::OnChannelRead(TransportChannel* channel, |
| 429 const char* data, size_t len, | 467 const char* data, size_t len, |
| 430 const rtc::PacketTime& packet_time, | 468 const rtc::PacketTime& packet_time, |
| 431 int flags) { | 469 int flags) { |
| 432 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine | 470 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine |
| 433 ASSERT(worker_thread_ == rtc::Thread::Current()); | 471 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 434 | 472 |
| 435 // When using RTCP multiplexing we might get RTCP packets on the RTP | 473 // When using RTCP multiplexing we might get RTCP packets on the RTP |
| 436 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. | 474 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. |
| 437 bool rtcp = PacketIsRtcp(channel, data, len); | 475 bool rtcp = PacketIsRtcp(channel, data, len); |
| 438 rtc::Buffer packet(data, len); | 476 rtc::Buffer packet(data, len); |
| 439 HandlePacket(rtcp, &packet, packet_time); | 477 HandlePacket(rtcp, &packet, packet_time); |
| 440 } | 478 } |
| 441 | 479 |
| 442 void BaseChannel::OnReadyToSend(TransportChannel* channel) { | 480 void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
| 443 SetReadyToSend(channel, true); | 481 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| 482 SetReadyToSend(channel == rtcp_transport_channel_, true); |
| 444 } | 483 } |
| 445 | 484 |
| 446 void BaseChannel::SetReadyToSend(TransportChannel* channel, bool ready) { | 485 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
| 447 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 486 if (rtcp) { |
| 448 if (channel == transport_channel_) { | 487 rtcp_ready_to_send_ = ready; |
| 488 } else { |
| 449 rtp_ready_to_send_ = ready; | 489 rtp_ready_to_send_ = ready; |
| 450 } | 490 } |
| 451 if (channel == rtcp_transport_channel_) { | |
| 452 rtcp_ready_to_send_ = ready; | |
| 453 } | |
| 454 | 491 |
| 455 if (!ready) { | 492 if (rtp_ready_to_send_ && |
| 493 // In the case of rtcp mux |rtcp_transport_channel_| will be null. |
| 494 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { |
| 495 // Notify the MediaChannel when both rtp and rtcp channel can send. |
| 496 media_channel_->OnReadyToSend(true); |
| 497 } else { |
| 456 // Notify the MediaChannel when either rtp or rtcp channel can't send. | 498 // Notify the MediaChannel when either rtp or rtcp channel can't send. |
| 457 media_channel_->OnReadyToSend(false); | 499 media_channel_->OnReadyToSend(false); |
| 458 } else if (rtp_ready_to_send_ && | |
| 459 // In the case of rtcp mux |rtcp_transport_channel_| will be null. | |
| 460 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { | |
| 461 // Notify the MediaChannel when both rtp and rtcp channel can send. | |
| 462 media_channel_->OnReadyToSend(true); | |
| 463 } | 500 } |
| 464 } | 501 } |
| 465 | 502 |
| 466 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, | 503 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, |
| 467 const char* data, size_t len) { | 504 const char* data, size_t len) { |
| 468 return (channel == rtcp_transport_channel_ || | 505 return (channel == rtcp_transport_channel_ || |
| 469 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); | 506 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); |
| 470 } | 507 } |
| 471 | 508 |
| 472 bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, | 509 bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 return false; | 611 return false; |
| 575 } | 612 } |
| 576 | 613 |
| 577 // Bon voyage. | 614 // Bon voyage. |
| 578 int ret = | 615 int ret = |
| 579 channel->SendPacket(packet->data<char>(), packet->size(), options, | 616 channel->SendPacket(packet->data<char>(), packet->size(), options, |
| 580 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); | 617 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); |
| 581 if (ret != static_cast<int>(packet->size())) { | 618 if (ret != static_cast<int>(packet->size())) { |
| 582 if (channel->GetError() == EWOULDBLOCK) { | 619 if (channel->GetError() == EWOULDBLOCK) { |
| 583 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; | 620 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; |
| 584 SetReadyToSend(channel, false); | 621 SetReadyToSend(rtcp, false); |
| 585 } | 622 } |
| 586 return false; | 623 return false; |
| 587 } | 624 } |
| 588 return true; | 625 return true; |
| 589 } | 626 } |
| 590 | 627 |
| 591 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { | 628 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { |
| 592 // Protect ourselves against crazy data. | 629 // Protect ourselves against crazy data. |
| 593 if (!ValidPacket(rtcp, packet)) { | 630 if (!ValidPacket(rtcp, packet)) { |
| 594 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " | 631 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 void BaseChannel::DisableMedia_w() { | 745 void BaseChannel::DisableMedia_w() { |
| 709 ASSERT(worker_thread_ == rtc::Thread::Current()); | 746 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 710 if (!enabled_) | 747 if (!enabled_) |
| 711 return; | 748 return; |
| 712 | 749 |
| 713 LOG(LS_INFO) << "Channel disabled"; | 750 LOG(LS_INFO) << "Channel disabled"; |
| 714 enabled_ = false; | 751 enabled_ = false; |
| 715 ChangeState(); | 752 ChangeState(); |
| 716 } | 753 } |
| 717 | 754 |
| 755 void BaseChannel::UpdateWritableState_w() { |
| 756 if (transport_channel_ && transport_channel_->writable() && |
| 757 (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { |
| 758 ChannelWritable_w(); |
| 759 } else { |
| 760 ChannelNotWritable_w(); |
| 761 } |
| 762 } |
| 763 |
| 718 void BaseChannel::ChannelWritable_w() { | 764 void BaseChannel::ChannelWritable_w() { |
| 719 ASSERT(worker_thread_ == rtc::Thread::Current()); | 765 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 720 if (writable_) | 766 if (writable_) |
| 721 return; | 767 return; |
| 722 | 768 |
| 723 LOG(LS_INFO) << "Channel socket writable (" | 769 LOG(LS_INFO) << "Channel writable (" << content_name_ << ")" |
| 724 << transport_channel_->content_name() << ", " | |
| 725 << transport_channel_->component() << ")" | |
| 726 << (was_ever_writable_ ? "" : " for the first time"); | 770 << (was_ever_writable_ ? "" : " for the first time"); |
| 727 | 771 |
| 728 std::vector<ConnectionInfo> infos; | 772 std::vector<ConnectionInfo> infos; |
| 729 transport_channel_->GetStats(&infos); | 773 transport_channel_->GetStats(&infos); |
| 730 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); | 774 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); |
| 731 it != infos.end(); ++it) { | 775 it != infos.end(); ++it) { |
| 732 if (it->best_connection) { | 776 if (it->best_connection) { |
| 733 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() | 777 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() |
| 734 << "->" << it->remote_candidate.ToSensitiveString(); | 778 << "->" << it->remote_candidate.ToSensitiveString(); |
| 735 break; | 779 break; |
| 736 } | 780 } |
| 737 } | 781 } |
| 738 | 782 |
| 739 // If we're doing DTLS-SRTP, now is the time. | 783 // If we're doing DTLS-SRTP, now is the time. |
| 740 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { | 784 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { |
| 741 if (!SetupDtlsSrtp(false)) { | 785 if (!SetupDtlsSrtp(false)) { |
| 742 SignalDtlsSetupFailure(this, false); | 786 SignalDtlsSetupFailure_w(false); |
| 743 return; | 787 return; |
| 744 } | 788 } |
| 745 | 789 |
| 746 if (rtcp_transport_channel_) { | 790 if (rtcp_transport_channel_) { |
| 747 if (!SetupDtlsSrtp(true)) { | 791 if (!SetupDtlsSrtp(true)) { |
| 748 SignalDtlsSetupFailure(this, true); | 792 SignalDtlsSetupFailure_w(true); |
| 749 return; | 793 return; |
| 750 } | 794 } |
| 751 } | 795 } |
| 752 } | 796 } |
| 753 | 797 |
| 754 was_ever_writable_ = true; | 798 was_ever_writable_ = true; |
| 755 writable_ = true; | 799 writable_ = true; |
| 756 ChangeState(); | 800 ChangeState(); |
| 757 } | 801 } |
| 758 | 802 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 781 | 825 |
| 782 bool BaseChannel::ShouldSetupDtlsSrtp() const { | 826 bool BaseChannel::ShouldSetupDtlsSrtp() const { |
| 783 return true; | 827 return true; |
| 784 } | 828 } |
| 785 | 829 |
| 786 // This function returns true if either DTLS-SRTP is not in use | 830 // This function returns true if either DTLS-SRTP is not in use |
| 787 // *or* DTLS-SRTP is successfully set up. | 831 // *or* DTLS-SRTP is successfully set up. |
| 788 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { | 832 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { |
| 789 bool ret = false; | 833 bool ret = false; |
| 790 | 834 |
| 791 TransportChannel *channel = rtcp_channel ? | 835 TransportChannel* channel = |
| 792 rtcp_transport_channel_ : transport_channel_; | 836 rtcp_channel ? rtcp_transport_channel_ : transport_channel_; |
| 793 | 837 |
| 794 // No DTLS | 838 // No DTLS |
| 795 if (!channel->IsDtlsActive()) | 839 if (!channel->IsDtlsActive()) |
| 796 return true; | 840 return true; |
| 797 | 841 |
| 798 std::string selected_cipher; | 842 std::string selected_cipher; |
| 799 | 843 |
| 800 if (!channel->GetSrtpCipher(&selected_cipher)) { | 844 if (!channel->GetSrtpCipher(&selected_cipher)) { |
| 801 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher"; | 845 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher"; |
| 802 return false; | 846 return false; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 dtls_keyed_ = true; | 921 dtls_keyed_ = true; |
| 878 | 922 |
| 879 return ret; | 923 return ret; |
| 880 } | 924 } |
| 881 | 925 |
| 882 void BaseChannel::ChannelNotWritable_w() { | 926 void BaseChannel::ChannelNotWritable_w() { |
| 883 ASSERT(worker_thread_ == rtc::Thread::Current()); | 927 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 884 if (!writable_) | 928 if (!writable_) |
| 885 return; | 929 return; |
| 886 | 930 |
| 887 LOG(LS_INFO) << "Channel socket not writable (" | 931 LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")"; |
| 888 << transport_channel_->content_name() << ", " | |
| 889 << transport_channel_->component() << ")"; | |
| 890 writable_ = false; | 932 writable_ = false; |
| 891 ChangeState(); | 933 ChangeState(); |
| 892 } | 934 } |
| 893 | 935 |
| 894 bool BaseChannel::SetRtpTransportParameters_w( | 936 bool BaseChannel::SetRtpTransportParameters_w( |
| 895 const MediaContentDescription* content, | 937 const MediaContentDescription* content, |
| 896 ContentAction action, | 938 ContentAction action, |
| 897 ContentSource src, | 939 ContentSource src, |
| 898 std::string* error_desc) { | 940 std::string* error_desc) { |
| 899 if (action == CA_UPDATE) { | 941 if (action == CA_UPDATE) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 } | 1020 } |
| 979 | 1021 |
| 980 void BaseChannel::ActivateRtcpMux() { | 1022 void BaseChannel::ActivateRtcpMux() { |
| 981 worker_thread_->Invoke<void>(Bind( | 1023 worker_thread_->Invoke<void>(Bind( |
| 982 &BaseChannel::ActivateRtcpMux_w, this)); | 1024 &BaseChannel::ActivateRtcpMux_w, this)); |
| 983 } | 1025 } |
| 984 | 1026 |
| 985 void BaseChannel::ActivateRtcpMux_w() { | 1027 void BaseChannel::ActivateRtcpMux_w() { |
| 986 if (!rtcp_mux_filter_.IsActive()) { | 1028 if (!rtcp_mux_filter_.IsActive()) { |
| 987 rtcp_mux_filter_.SetActive(); | 1029 rtcp_mux_filter_.SetActive(); |
| 988 set_rtcp_transport_channel(NULL); | 1030 set_rtcp_transport_channel(nullptr); |
| 1031 rtcp_transport_enabled_ = false; |
| 989 } | 1032 } |
| 990 } | 1033 } |
| 991 | 1034 |
| 992 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, | 1035 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, |
| 993 ContentSource src, | 1036 ContentSource src, |
| 994 std::string* error_desc) { | 1037 std::string* error_desc) { |
| 995 bool ret = false; | 1038 bool ret = false; |
| 996 switch (action) { | 1039 switch (action) { |
| 997 case CA_OFFER: | 1040 case CA_OFFER: |
| 998 ret = rtcp_mux_filter_.SetOffer(enable, src); | 1041 ret = rtcp_mux_filter_.SetOffer(enable, src); |
| 999 break; | 1042 break; |
| 1000 case CA_PRANSWER: | 1043 case CA_PRANSWER: |
| 1001 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); | 1044 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); |
| 1002 break; | 1045 break; |
| 1003 case CA_ANSWER: | 1046 case CA_ANSWER: |
| 1004 ret = rtcp_mux_filter_.SetAnswer(enable, src); | 1047 ret = rtcp_mux_filter_.SetAnswer(enable, src); |
| 1005 if (ret && rtcp_mux_filter_.IsActive()) { | 1048 if (ret && rtcp_mux_filter_.IsActive()) { |
| 1006 // We activated RTCP mux, close down the RTCP transport. | 1049 // We activated RTCP mux, close down the RTCP transport. |
| 1007 set_rtcp_transport_channel(NULL); | 1050 LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() |
| 1051 << " by destroying RTCP transport channel for " |
| 1052 << transport_name(); |
| 1053 set_rtcp_transport_channel(nullptr); |
| 1054 rtcp_transport_enabled_ = false; |
| 1008 } | 1055 } |
| 1009 break; | 1056 break; |
| 1010 case CA_UPDATE: | 1057 case CA_UPDATE: |
| 1011 // No RTCP mux info. | 1058 // No RTCP mux info. |
| 1012 ret = true; | 1059 ret = true; |
| 1013 break; | 1060 break; |
| 1014 default: | 1061 default: |
| 1015 break; | 1062 break; |
| 1016 } | 1063 } |
| 1017 if (!ret) { | 1064 if (!ret) { |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 worker_thread_->Clear(this, MSG_RTCPPACKET, &rtcp_messages); | 1271 worker_thread_->Clear(this, MSG_RTCPPACKET, &rtcp_messages); |
| 1225 for (rtc::MessageList::iterator it = rtcp_messages.begin(); | 1272 for (rtc::MessageList::iterator it = rtcp_messages.begin(); |
| 1226 it != rtcp_messages.end(); ++it) { | 1273 it != rtcp_messages.end(); ++it) { |
| 1227 worker_thread_->Send(this, MSG_RTCPPACKET, it->pdata); | 1274 worker_thread_->Send(this, MSG_RTCPPACKET, it->pdata); |
| 1228 } | 1275 } |
| 1229 } | 1276 } |
| 1230 | 1277 |
| 1231 VoiceChannel::VoiceChannel(rtc::Thread* thread, | 1278 VoiceChannel::VoiceChannel(rtc::Thread* thread, |
| 1232 MediaEngineInterface* media_engine, | 1279 MediaEngineInterface* media_engine, |
| 1233 VoiceMediaChannel* media_channel, | 1280 VoiceMediaChannel* media_channel, |
| 1234 BaseSession* session, | 1281 TransportController* transport_controller, |
| 1235 const std::string& content_name, | 1282 const std::string& content_name, |
| 1236 bool rtcp) | 1283 bool rtcp) |
| 1237 : BaseChannel(thread, media_channel, session, content_name, | 1284 : BaseChannel(thread, |
| 1285 media_channel, |
| 1286 transport_controller, |
| 1287 content_name, |
| 1238 rtcp), | 1288 rtcp), |
| 1239 media_engine_(media_engine), | 1289 media_engine_(media_engine), |
| 1240 received_media_(false) { | 1290 received_media_(false) {} |
| 1241 } | |
| 1242 | 1291 |
| 1243 VoiceChannel::~VoiceChannel() { | 1292 VoiceChannel::~VoiceChannel() { |
| 1244 StopAudioMonitor(); | 1293 StopAudioMonitor(); |
| 1245 StopMediaMonitor(); | 1294 StopMediaMonitor(); |
| 1246 // this can't be done in the base class, since it calls a virtual | 1295 // this can't be done in the base class, since it calls a virtual |
| 1247 DisableMedia_w(); | 1296 DisableMedia_w(); |
| 1248 Deinit(); | 1297 Deinit(); |
| 1249 } | 1298 } |
| 1250 | 1299 |
| 1251 bool VoiceChannel::Init() { | 1300 bool VoiceChannel::Init() { |
| 1252 if (!BaseChannel::Init()) { | 1301 if (!BaseChannel::Init()) { |
| 1253 return false; | 1302 return false; |
| 1254 } | 1303 } |
| 1255 media_channel()->SignalMediaError.connect( | 1304 media_channel()->SignalMediaError.connect( |
| 1256 this, &VoiceChannel::OnVoiceChannelError); | 1305 this, &VoiceChannel::OnVoiceChannelError); |
| 1257 srtp_filter()->SignalSrtpError.connect( | 1306 srtp_filter()->SignalSrtpError.connect( |
| 1258 this, &VoiceChannel::OnSrtpError); | 1307 this, &VoiceChannel::OnSrtpError); |
| 1259 return true; | 1308 return true; |
| 1260 } | 1309 } |
| 1261 | 1310 |
| 1262 bool VoiceChannel::SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) { | 1311 bool VoiceChannel::SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) { |
| 1263 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetRemoteRenderer, | 1312 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetRemoteRenderer, |
| 1264 media_channel(), ssrc, renderer)); | 1313 media_channel(), ssrc, renderer)); |
| 1265 } | 1314 } |
| 1266 | 1315 |
| 1267 bool VoiceChannel::SetAudioSend(uint32 ssrc, bool mute, | 1316 bool VoiceChannel::SetAudioSend(uint32 ssrc, |
| 1317 bool mute, |
| 1268 const AudioOptions* options, | 1318 const AudioOptions* options, |
| 1269 AudioRenderer* renderer) { | 1319 AudioRenderer* renderer) { |
| 1270 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetAudioSend, | 1320 return InvokeOnWorker(Bind(&VoiceMediaChannel::SetAudioSend, media_channel(), |
| 1271 media_channel(), ssrc, mute, options, renderer)); | 1321 ssrc, mute, options, renderer)); |
| 1272 } | 1322 } |
| 1273 | 1323 |
| 1274 bool VoiceChannel::SetRingbackTone(const void* buf, int len) { | 1324 bool VoiceChannel::SetRingbackTone(const void* buf, int len) { |
| 1275 return InvokeOnWorker(Bind(&VoiceChannel::SetRingbackTone_w, this, buf, len)); | 1325 return InvokeOnWorker(Bind(&VoiceChannel::SetRingbackTone_w, this, buf, len)); |
| 1276 } | 1326 } |
| 1277 | 1327 |
| 1278 // TODO(juberti): Handle early media the right way. We should get an explicit | 1328 // TODO(juberti): Handle early media the right way. We should get an explicit |
| 1279 // ringing message telling us to start playing local ringback, which we cancel | 1329 // ringing message telling us to start playing local ringback, which we cancel |
| 1280 // if any early media actually arrives. For now, we do the opposite, which is | 1330 // if any early media actually arrives. For now, we do the opposite, which is |
| 1281 // to wait 1 second for early media, and start playing local ringback if none | 1331 // to wait 1 second for early media, and start playing local ringback if none |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 break; | 1650 break; |
| 1601 } | 1651 } |
| 1602 } | 1652 } |
| 1603 | 1653 |
| 1604 void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { | 1654 void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { |
| 1605 GetSupportedAudioCryptoSuites(ciphers); | 1655 GetSupportedAudioCryptoSuites(ciphers); |
| 1606 } | 1656 } |
| 1607 | 1657 |
| 1608 VideoChannel::VideoChannel(rtc::Thread* thread, | 1658 VideoChannel::VideoChannel(rtc::Thread* thread, |
| 1609 VideoMediaChannel* media_channel, | 1659 VideoMediaChannel* media_channel, |
| 1610 BaseSession* session, | 1660 TransportController* transport_controller, |
| 1611 const std::string& content_name, | 1661 const std::string& content_name, |
| 1612 bool rtcp) | 1662 bool rtcp) |
| 1613 : BaseChannel(thread, media_channel, session, content_name, | 1663 : BaseChannel(thread, |
| 1664 media_channel, |
| 1665 transport_controller, |
| 1666 content_name, |
| 1614 rtcp), | 1667 rtcp), |
| 1615 renderer_(NULL), | 1668 renderer_(NULL), |
| 1616 previous_we_(rtc::WE_CLOSE) { | 1669 previous_we_(rtc::WE_CLOSE) {} |
| 1617 } | |
| 1618 | 1670 |
| 1619 bool VideoChannel::Init() { | 1671 bool VideoChannel::Init() { |
| 1620 if (!BaseChannel::Init()) { | 1672 if (!BaseChannel::Init()) { |
| 1621 return false; | 1673 return false; |
| 1622 } | 1674 } |
| 1623 media_channel()->SignalMediaError.connect( | 1675 media_channel()->SignalMediaError.connect( |
| 1624 this, &VideoChannel::OnVideoChannelError); | 1676 this, &VideoChannel::OnVideoChannelError); |
| 1625 srtp_filter()->SignalSrtpError.connect( | 1677 srtp_filter()->SignalSrtpError.connect( |
| 1626 this, &VideoChannel::OnSrtpError); | 1678 this, &VideoChannel::OnSrtpError); |
| 1627 return true; | 1679 return true; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 &VideoMediaChannel::SendIntraFrame, media_channel())); | 1752 &VideoMediaChannel::SendIntraFrame, media_channel())); |
| 1701 return true; | 1753 return true; |
| 1702 } | 1754 } |
| 1703 | 1755 |
| 1704 bool VideoChannel::RequestIntraFrame() { | 1756 bool VideoChannel::RequestIntraFrame() { |
| 1705 worker_thread()->Invoke<void>(Bind( | 1757 worker_thread()->Invoke<void>(Bind( |
| 1706 &VideoMediaChannel::RequestIntraFrame, media_channel())); | 1758 &VideoMediaChannel::RequestIntraFrame, media_channel())); |
| 1707 return true; | 1759 return true; |
| 1708 } | 1760 } |
| 1709 | 1761 |
| 1710 bool VideoChannel::SetVideoSend(uint32 ssrc, bool mute, | 1762 bool VideoChannel::SetVideoSend(uint32 ssrc, |
| 1763 bool mute, |
| 1711 const VideoOptions* options) { | 1764 const VideoOptions* options) { |
| 1712 return InvokeOnWorker(Bind(&VideoMediaChannel::SetVideoSend, | 1765 return InvokeOnWorker(Bind(&VideoMediaChannel::SetVideoSend, media_channel(), |
| 1713 media_channel(), ssrc, mute, options)); | 1766 ssrc, mute, options)); |
| 1714 } | 1767 } |
| 1715 | 1768 |
| 1716 void VideoChannel::ChangeState() { | 1769 void VideoChannel::ChangeState() { |
| 1717 // Render incoming data if we're the active call, and we have the local | 1770 // Render incoming data if we're the active call, and we have the local |
| 1718 // content. We receive data on the default channel and multiplexed streams. | 1771 // content. We receive data on the default channel and multiplexed streams. |
| 1719 bool recv = IsReadyToReceive(); | 1772 bool recv = IsReadyToReceive(); |
| 1720 if (!media_channel()->SetRender(recv)) { | 1773 if (!media_channel()->SetRender(recv)) { |
| 1721 LOG(LS_ERROR) << "Failed to SetRender on video channel"; | 1774 LOG(LS_ERROR) << "Failed to SetRender on video channel"; |
| 1722 // TODO(gangji): Report error back to server. | 1775 // TODO(gangji): Report error back to server. |
| 1723 } | 1776 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2038 break; | 2091 break; |
| 2039 } | 2092 } |
| 2040 } | 2093 } |
| 2041 | 2094 |
| 2042 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { | 2095 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { |
| 2043 GetSupportedVideoCryptoSuites(ciphers); | 2096 GetSupportedVideoCryptoSuites(ciphers); |
| 2044 } | 2097 } |
| 2045 | 2098 |
| 2046 DataChannel::DataChannel(rtc::Thread* thread, | 2099 DataChannel::DataChannel(rtc::Thread* thread, |
| 2047 DataMediaChannel* media_channel, | 2100 DataMediaChannel* media_channel, |
| 2048 BaseSession* session, | 2101 TransportController* transport_controller, |
| 2049 const std::string& content_name, | 2102 const std::string& content_name, |
| 2050 bool rtcp) | 2103 bool rtcp) |
| 2051 : BaseChannel(thread, media_channel, session, content_name, rtcp), | 2104 : BaseChannel(thread, |
| 2105 media_channel, |
| 2106 transport_controller, |
| 2107 content_name, |
| 2108 rtcp), |
| 2052 data_channel_type_(cricket::DCT_NONE), | 2109 data_channel_type_(cricket::DCT_NONE), |
| 2053 ready_to_send_data_(false) { | 2110 ready_to_send_data_(false) {} |
| 2054 } | |
| 2055 | 2111 |
| 2056 DataChannel::~DataChannel() { | 2112 DataChannel::~DataChannel() { |
| 2057 StopMediaMonitor(); | 2113 StopMediaMonitor(); |
| 2058 // this can't be done in the base class, since it calls a virtual | 2114 // this can't be done in the base class, since it calls a virtual |
| 2059 DisableMedia_w(); | 2115 DisableMedia_w(); |
| 2060 | 2116 |
| 2061 Deinit(); | 2117 Deinit(); |
| 2062 } | 2118 } |
| 2063 | 2119 |
| 2064 bool DataChannel::Init() { | 2120 bool DataChannel::Init() { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2379 return (data_channel_type_ == DCT_RTP); | 2435 return (data_channel_type_ == DCT_RTP); |
| 2380 } | 2436 } |
| 2381 | 2437 |
| 2382 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2438 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
| 2383 rtc::TypedMessageData<uint32>* message = | 2439 rtc::TypedMessageData<uint32>* message = |
| 2384 new rtc::TypedMessageData<uint32>(sid); | 2440 new rtc::TypedMessageData<uint32>(sid); |
| 2385 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2441 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
| 2386 } | 2442 } |
| 2387 | 2443 |
| 2388 } // namespace cricket | 2444 } // namespace cricket |
| OLD | NEW |