Chromium Code Reviews| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 MSG_DATARECEIVED, | 53 MSG_DATARECEIVED, |
| 54 MSG_FIRSTPACKETRECEIVED, | 54 MSG_FIRSTPACKETRECEIVED, |
| 55 MSG_STREAMCLOSEDREMOTELY, | 55 MSG_STREAMCLOSEDREMOTELY, |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 // Value specified in RFC 5764. | 58 // Value specified in RFC 5764. |
| 59 static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp"; | 59 static const char kDtlsSrtpExporterLabel[] = "EXTRACTOR-dtls_srtp"; |
| 60 | 60 |
| 61 static const int kAgcMinus10db = -10; | 61 static const int kAgcMinus10db = -10; |
| 62 | 62 |
| 63 static void SetSessionError(BaseSession* session, BaseSession::Error error, | |
| 64 const std::string& error_desc) { | |
| 65 session->SetError(error, error_desc); | |
| 66 } | |
| 67 | |
| 68 static void SafeSetError(const std::string& message, std::string* error_desc) { | 63 static void SafeSetError(const std::string& message, std::string* error_desc) { |
| 69 if (error_desc) { | 64 if (error_desc) { |
| 70 *error_desc = message; | 65 *error_desc = message; |
| 71 } | 66 } |
| 72 } | 67 } |
| 73 | 68 |
| 74 struct PacketMessageData : public rtc::MessageData { | 69 struct PacketMessageData : public rtc::MessageData { |
| 75 rtc::Buffer packet; | 70 rtc::Buffer packet; |
| 76 rtc::DiffServCodePoint dscp; | 71 rtc::DiffServCodePoint dscp; |
| 77 }; | 72 }; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 } | 139 } |
| 145 | 140 |
| 146 static const MediaContentDescription* GetContentDescription( | 141 static const MediaContentDescription* GetContentDescription( |
| 147 const ContentInfo* cinfo) { | 142 const ContentInfo* cinfo) { |
| 148 if (cinfo == NULL) | 143 if (cinfo == NULL) |
| 149 return NULL; | 144 return NULL; |
| 150 return static_cast<const MediaContentDescription*>(cinfo->description); | 145 return static_cast<const MediaContentDescription*>(cinfo->description); |
| 151 } | 146 } |
| 152 | 147 |
| 153 BaseChannel::BaseChannel(rtc::Thread* thread, | 148 BaseChannel::BaseChannel(rtc::Thread* thread, |
| 154 MediaChannel* media_channel, BaseSession* session, | 149 MediaChannel* media_channel, |
| 155 const std::string& content_name, bool rtcp) | 150 TransportController* transport_controller, |
| 151 const std::string& content_name, | |
| 152 bool rtcp) | |
| 156 : worker_thread_(thread), | 153 : worker_thread_(thread), |
| 157 session_(session), | 154 transport_controller_(transport_controller), |
| 158 media_channel_(media_channel), | 155 media_channel_(media_channel), |
| 159 content_name_(content_name), | 156 content_name_(content_name), |
| 160 rtcp_(rtcp), | 157 rtcp_(rtcp), |
| 161 transport_channel_(NULL), | 158 transport_channel_(NULL), |
| 162 rtcp_transport_channel_(NULL), | 159 rtcp_transport_channel_(NULL), |
| 163 enabled_(false), | 160 enabled_(false), |
| 164 writable_(false), | 161 writable_(false), |
| 165 rtp_ready_to_send_(false), | 162 rtp_ready_to_send_(false), |
| 166 rtcp_ready_to_send_(false), | 163 rtcp_ready_to_send_(false), |
| 167 was_ever_writable_(false), | 164 was_ever_writable_(false), |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 178 BaseChannel::~BaseChannel() { | 175 BaseChannel::~BaseChannel() { |
| 179 ASSERT(worker_thread_ == rtc::Thread::Current()); | 176 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 180 Deinit(); | 177 Deinit(); |
| 181 StopConnectionMonitor(); | 178 StopConnectionMonitor(); |
| 182 FlushRtcpMessages(); // Send any outstanding RTCP packets. | 179 FlushRtcpMessages(); // Send any outstanding RTCP packets. |
| 183 worker_thread_->Clear(this); // eats any outstanding messages or packets | 180 worker_thread_->Clear(this); // eats any outstanding messages or packets |
| 184 // We must destroy the media channel before the transport channel, otherwise | 181 // We must destroy the media channel before the transport channel, otherwise |
| 185 // the media channel may try to send on the dead transport channel. NULLing | 182 // the media channel may try to send on the dead transport channel. NULLing |
| 186 // is not an effective strategy since the sends will come on another thread. | 183 // is not an effective strategy since the sends will come on another thread. |
| 187 delete media_channel_; | 184 delete media_channel_; |
| 188 set_transport_channel(nullptr); | 185 if (transport_channel_) { |
| 189 set_rtcp_transport_channel(nullptr); | 186 DisconnectFromTransportChannel(transport_channel_); |
| 187 transport_controller_->DestroyTransportChannel_w( | |
| 188 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); | |
| 189 } | |
| 190 if (rtcp_transport_channel_) { | |
| 191 DisconnectFromTransportChannel(rtcp_transport_channel_); | |
| 192 transport_controller_->DestroyTransportChannel_w( | |
| 193 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); | |
| 194 } | |
| 190 LOG(LS_INFO) << "Destroyed channel"; | 195 LOG(LS_INFO) << "Destroyed channel"; |
| 191 } | 196 } |
| 192 | 197 |
| 193 bool BaseChannel::Init() { | 198 bool BaseChannel::Init() { |
| 194 if (!SetTransportChannels(session(), rtcp())) { | 199 if (!SetTransportChannels(content_name(), rtcp())) { |
| 195 return false; | 200 return false; |
| 196 } | 201 } |
| 197 | 202 |
| 198 if (!SetDtlsSrtpCiphers(transport_channel(), false)) { | 203 if (!SetDtlsSrtpCiphers(transport_channel(), false)) { |
| 199 return false; | 204 return false; |
| 200 } | 205 } |
| 201 if (rtcp() && !SetDtlsSrtpCiphers(rtcp_transport_channel(), true)) { | 206 if (rtcp() && !SetDtlsSrtpCiphers(rtcp_transport_channel(), true)) { |
| 202 return false; | 207 return false; |
| 203 } | 208 } |
| 204 | 209 |
| 205 // Both RTP and RTCP channels are set, we can call SetInterface on | 210 // Both RTP and RTCP channels are set, we can call SetInterface on |
| 206 // media channel and it can set network options. | 211 // media channel and it can set network options. |
| 207 media_channel_->SetInterface(this); | 212 media_channel_->SetInterface(this); |
| 208 return true; | 213 return true; |
| 209 } | 214 } |
| 210 | 215 |
| 211 void BaseChannel::Deinit() { | 216 void BaseChannel::Deinit() { |
| 212 media_channel_->SetInterface(NULL); | 217 media_channel_->SetInterface(NULL); |
| 213 } | 218 } |
| 214 | 219 |
| 215 bool BaseChannel::SetTransportChannels(BaseSession* session, bool rtcp) { | 220 bool BaseChannel::SetTransport(const std::string& transport_name) { |
| 216 return worker_thread_->Invoke<bool>(Bind( | 221 // Only enable an RTCP transport channel if we already had one. |
| 217 &BaseChannel::SetTransportChannels_w, this, session, rtcp)); | 222 bool rtcp = (rtcp_transport_channel() != nullptr); |
| 223 if (!SetTransportChannels(transport_name, rtcp)) { | |
| 224 return false; | |
| 225 } | |
| 226 return true; | |
| 218 } | 227 } |
| 219 | 228 |
| 220 bool BaseChannel::SetTransportChannels_w(BaseSession* session, bool rtcp) { | 229 bool BaseChannel::SetTransportChannels(const std::string& transport_name, |
| 230 bool rtcp) { | |
| 231 return worker_thread_->Invoke<bool>( | |
| 232 Bind(&BaseChannel::SetTransportChannels_w, this, transport_name, rtcp)); | |
| 233 } | |
| 234 | |
| 235 bool BaseChannel::SetTransportChannels_w(const std::string& transport_name, | |
| 236 bool rtcp) { | |
| 221 ASSERT(worker_thread_ == rtc::Thread::Current()); | 237 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 222 | 238 |
| 223 set_transport_channel(session->CreateChannel( | 239 if (transport_name != transport_name_) { |
| 224 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP)); | 240 set_transport_channel(transport_controller_->CreateTransportChannel_w( |
|
pthatcher1
2015/08/18 22:32:47
Even though it's called "create", it's more like "
Taylor Brandstetter
2015/08/25 01:04:05
This just avoids incrementing the ref count pointl
pthatcher1
2015/08/25 18:40:38
If you call:
SetTransportChannels("audio", true);
Taylor Brandstetter
2015/08/25 20:39:54
*Initially* we'll add a ref count to each channel,
pthatcher1
2015/08/25 21:19:49
OK, I think I get what you're saying now. I misre
Taylor Brandstetter
2015/08/27 22:15:57
I followed your suggestion and also removed the "r
| |
| 225 if (!transport_channel()) { | 241 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); |
| 226 return false; | 242 if (!transport_channel()) { |
| 243 return false; | |
| 244 } | |
| 227 } | 245 } |
| 228 if (rtcp) { | 246 if (rtcp) { |
| 229 set_rtcp_transport_channel(session->CreateChannel( | 247 if (!rtcp_transport_channel_ || transport_name != transport_name_) { |
| 230 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP)); | 248 LOG(LS_INFO) << "Create RTCP TransportChannel for " << content_name() |
| 231 if (!rtcp_transport_channel()) { | 249 << " on " << transport_name << " transport "; |
| 232 return false; | 250 set_rtcp_transport_channel( |
| 251 transport_controller_->CreateTransportChannel_w( | |
| 252 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP)); | |
| 253 if (!rtcp_transport_channel()) { | |
| 254 return false; | |
| 255 } | |
| 233 } | 256 } |
| 234 } else { | 257 } else { |
| 235 set_rtcp_transport_channel(nullptr); | 258 set_rtcp_transport_channel(nullptr); |
| 236 } | 259 } |
| 260 transport_name_ = transport_name; | |
| 237 | 261 |
| 238 return true; | 262 return true; |
| 239 } | 263 } |
| 240 | 264 |
| 241 void BaseChannel::set_transport_channel(TransportChannel* new_tc) { | 265 void BaseChannel::set_transport_channel(TransportChannel* new_tc) { |
| 242 ASSERT(worker_thread_ == rtc::Thread::Current()); | 266 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 243 | 267 |
| 244 TransportChannel* old_tc = transport_channel_; | 268 TransportChannel* old_tc = transport_channel_; |
| 245 | |
| 246 if (old_tc == new_tc) { | |
| 247 return; | |
| 248 } | |
| 249 if (old_tc) { | 269 if (old_tc) { |
| 250 DisconnectFromTransportChannel(old_tc); | 270 DisconnectFromTransportChannel(old_tc); |
| 251 session()->DestroyChannel( | 271 transport_controller_->DestroyTransportChannel_w( |
| 252 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP); | 272 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTP); |
| 253 } | 273 } |
| 254 | 274 |
| 255 transport_channel_ = new_tc; | 275 transport_channel_ = new_tc; |
| 256 | 276 |
| 257 if (new_tc) { | 277 if (new_tc) { |
| 258 ConnectToTransportChannel(new_tc); | 278 ConnectToTransportChannel(new_tc); |
| 279 for (const auto& pair : socket_options_) { | |
| 280 new_tc->SetOption(pair.first, pair.second); | |
| 281 } | |
| 259 } | 282 } |
| 283 | |
| 284 // Update aggregate writable/ready-to-send state upon setting new channel | |
|
pthatcher1
2015/08/18 22:32:47
It's not really aggregate. It's more like inherit
Taylor Brandstetter
2015/08/25 01:04:05
Well we have to aggregate the writable state from
pthatcher1
2015/08/25 18:40:38
That's a good point. Maybe mention that in the co
Taylor Brandstetter
2015/08/25 20:39:54
Done.
| |
| 285 UpdateWritableState_w(); | |
| 286 SetReadyToSend(false, new_tc && new_tc->writable()); | |
| 260 } | 287 } |
| 261 | 288 |
| 262 void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { | 289 void BaseChannel::set_rtcp_transport_channel(TransportChannel* new_tc) { |
| 263 ASSERT(worker_thread_ == rtc::Thread::Current()); | 290 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 264 | 291 |
| 265 TransportChannel* old_tc = rtcp_transport_channel_; | 292 TransportChannel* old_tc = rtcp_transport_channel_; |
| 266 | |
| 267 if (old_tc == new_tc) { | |
| 268 return; | |
| 269 } | |
| 270 if (old_tc) { | 293 if (old_tc) { |
| 271 DisconnectFromTransportChannel(old_tc); | 294 DisconnectFromTransportChannel(old_tc); |
| 272 session()->DestroyChannel( | 295 transport_controller_->DestroyTransportChannel_w( |
| 273 content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP); | 296 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
| 274 } | 297 } |
| 275 | 298 |
| 276 rtcp_transport_channel_ = new_tc; | 299 rtcp_transport_channel_ = new_tc; |
| 277 | 300 |
| 278 if (new_tc) { | 301 if (new_tc) { |
| 279 ConnectToTransportChannel(new_tc); | 302 ConnectToTransportChannel(new_tc); |
| 303 for (const auto& pair : rtcp_socket_options_) { | |
| 304 new_tc->SetOption(pair.first, pair.second); | |
| 305 } | |
| 280 } | 306 } |
| 307 | |
| 308 // Update aggregate writable/ready-to-send state upon setting new channel | |
| 309 UpdateWritableState_w(); | |
| 310 SetReadyToSend(true, new_tc && new_tc->writable()); | |
| 281 } | 311 } |
| 282 | 312 |
| 283 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { | 313 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
| 284 ASSERT(worker_thread_ == rtc::Thread::Current()); | 314 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 285 | 315 |
| 286 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 316 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
| 287 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); | 317 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
| 288 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | 318 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
| 289 } | 319 } |
| 290 | 320 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 rtc::DiffServCodePoint dscp) { | 419 rtc::DiffServCodePoint dscp) { |
| 390 return SendPacket(true, packet, dscp); | 420 return SendPacket(true, packet, dscp); |
| 391 } | 421 } |
| 392 | 422 |
| 393 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, | 423 int BaseChannel::SetOption(SocketType type, rtc::Socket::Option opt, |
| 394 int value) { | 424 int value) { |
| 395 TransportChannel* channel = NULL; | 425 TransportChannel* channel = NULL; |
| 396 switch (type) { | 426 switch (type) { |
| 397 case ST_RTP: | 427 case ST_RTP: |
| 398 channel = transport_channel_; | 428 channel = transport_channel_; |
| 429 socket_options_.push_back( | |
| 430 std::pair<rtc::Socket::Option, int>(opt, value)); | |
| 399 break; | 431 break; |
| 400 case ST_RTCP: | 432 case ST_RTCP: |
| 401 channel = rtcp_transport_channel_; | 433 channel = rtcp_transport_channel_; |
| 434 rtcp_socket_options_.push_back( | |
| 435 std::pair<rtc::Socket::Option, int>(opt, value)); | |
| 402 break; | 436 break; |
| 403 } | 437 } |
| 404 return channel ? channel->SetOption(opt, value) : -1; | 438 return channel ? channel->SetOption(opt, value) : -1; |
| 405 } | 439 } |
| 406 | 440 |
| 407 void BaseChannel::OnWritableState(TransportChannel* channel) { | 441 void BaseChannel::OnWritableState(TransportChannel* channel) { |
| 408 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 442 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| 409 if (transport_channel_->writable() | 443 UpdateWritableState_w(); |
| 410 && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { | |
| 411 ChannelWritable_w(); | |
| 412 } else { | |
| 413 ChannelNotWritable_w(); | |
| 414 } | |
| 415 } | 444 } |
| 416 | 445 |
| 417 void BaseChannel::OnChannelRead(TransportChannel* channel, | 446 void BaseChannel::OnChannelRead(TransportChannel* channel, |
| 418 const char* data, size_t len, | 447 const char* data, size_t len, |
| 419 const rtc::PacketTime& packet_time, | 448 const rtc::PacketTime& packet_time, |
| 420 int flags) { | 449 int flags) { |
| 421 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine | 450 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine |
| 422 ASSERT(worker_thread_ == rtc::Thread::Current()); | 451 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 423 | 452 |
| 424 // When using RTCP multiplexing we might get RTCP packets on the RTP | 453 // When using RTCP multiplexing we might get RTCP packets on the RTP |
| 425 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. | 454 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. |
| 426 bool rtcp = PacketIsRtcp(channel, data, len); | 455 bool rtcp = PacketIsRtcp(channel, data, len); |
| 427 rtc::Buffer packet(data, len); | 456 rtc::Buffer packet(data, len); |
| 428 HandlePacket(rtcp, &packet, packet_time); | 457 HandlePacket(rtcp, &packet, packet_time); |
| 429 } | 458 } |
| 430 | 459 |
| 431 void BaseChannel::OnReadyToSend(TransportChannel* channel) { | 460 void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
| 432 SetReadyToSend(channel, true); | 461 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
| 462 SetReadyToSend(channel == rtcp_transport_channel_, true); | |
| 433 } | 463 } |
| 434 | 464 |
| 435 void BaseChannel::SetReadyToSend(TransportChannel* channel, bool ready) { | 465 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
| 436 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 466 if (rtcp) { |
| 437 if (channel == transport_channel_) { | 467 rtcp_ready_to_send_ = ready; |
| 468 } else { | |
| 438 rtp_ready_to_send_ = ready; | 469 rtp_ready_to_send_ = ready; |
| 439 } | 470 } |
| 440 if (channel == rtcp_transport_channel_) { | |
| 441 rtcp_ready_to_send_ = ready; | |
| 442 } | |
| 443 | 471 |
| 444 if (!ready) { | 472 if (rtp_ready_to_send_ && |
| 473 // In the case of rtcp mux |rtcp_transport_channel_| will be null. | |
| 474 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { | |
| 475 // Notify the MediaChannel when both rtp and rtcp channel can send. | |
| 476 media_channel_->OnReadyToSend(true); | |
| 477 } else { | |
| 445 // Notify the MediaChannel when either rtp or rtcp channel can't send. | 478 // Notify the MediaChannel when either rtp or rtcp channel can't send. |
| 446 media_channel_->OnReadyToSend(false); | 479 media_channel_->OnReadyToSend(false); |
| 447 } else if (rtp_ready_to_send_ && | |
| 448 // In the case of rtcp mux |rtcp_transport_channel_| will be null. | |
| 449 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { | |
| 450 // Notify the MediaChannel when both rtp and rtcp channel can send. | |
| 451 media_channel_->OnReadyToSend(true); | |
| 452 } | 480 } |
| 453 } | 481 } |
| 454 | 482 |
| 455 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, | 483 bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, |
| 456 const char* data, size_t len) { | 484 const char* data, size_t len) { |
| 457 return (channel == rtcp_transport_channel_ || | 485 return (channel == rtcp_transport_channel_ || |
| 458 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); | 486 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); |
| 459 } | 487 } |
| 460 | 488 |
| 461 bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, | 489 bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 return false; | 591 return false; |
| 564 } | 592 } |
| 565 | 593 |
| 566 // Bon voyage. | 594 // Bon voyage. |
| 567 int ret = | 595 int ret = |
| 568 channel->SendPacket(packet->data<char>(), packet->size(), options, | 596 channel->SendPacket(packet->data<char>(), packet->size(), options, |
| 569 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); | 597 (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); |
| 570 if (ret != static_cast<int>(packet->size())) { | 598 if (ret != static_cast<int>(packet->size())) { |
| 571 if (channel->GetError() == EWOULDBLOCK) { | 599 if (channel->GetError() == EWOULDBLOCK) { |
| 572 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; | 600 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; |
| 573 SetReadyToSend(channel, false); | 601 SetReadyToSend(rtcp, false); |
| 574 } | 602 } |
| 575 return false; | 603 return false; |
| 576 } | 604 } |
| 577 return true; | 605 return true; |
| 578 } | 606 } |
| 579 | 607 |
| 580 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { | 608 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { |
| 581 // Protect ourselves against crazy data. | 609 // Protect ourselves against crazy data. |
| 582 if (!ValidPacket(rtcp, packet)) { | 610 if (!ValidPacket(rtcp, packet)) { |
| 583 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " | 611 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 714 muted_streams_.erase(ssrc); | 742 muted_streams_.erase(ssrc); |
| 715 } | 743 } |
| 716 return ret; | 744 return ret; |
| 717 } | 745 } |
| 718 | 746 |
| 719 bool BaseChannel::IsStreamMuted_w(uint32 ssrc) { | 747 bool BaseChannel::IsStreamMuted_w(uint32 ssrc) { |
| 720 ASSERT(worker_thread_ == rtc::Thread::Current()); | 748 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 721 return muted_streams_.find(ssrc) != muted_streams_.end(); | 749 return muted_streams_.find(ssrc) != muted_streams_.end(); |
| 722 } | 750 } |
| 723 | 751 |
| 752 void BaseChannel::UpdateWritableState_w() { | |
| 753 if (transport_channel_ && transport_channel_->writable() && | |
| 754 (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { | |
| 755 ChannelWritable_w(); | |
| 756 } else { | |
| 757 ChannelNotWritable_w(); | |
| 758 } | |
| 759 } | |
| 760 | |
| 724 void BaseChannel::ChannelWritable_w() { | 761 void BaseChannel::ChannelWritable_w() { |
| 725 ASSERT(worker_thread_ == rtc::Thread::Current()); | 762 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 726 if (writable_) | 763 if (writable_) |
| 727 return; | 764 return; |
| 728 | 765 |
| 729 LOG(LS_INFO) << "Channel socket writable (" | 766 LOG(LS_INFO) << "Channel writable (" << content_name_ << ")" |
| 730 << transport_channel_->content_name() << ", " | |
| 731 << transport_channel_->component() << ")" | |
| 732 << (was_ever_writable_ ? "" : " for the first time"); | 767 << (was_ever_writable_ ? "" : " for the first time"); |
| 733 | 768 |
| 734 std::vector<ConnectionInfo> infos; | 769 std::vector<ConnectionInfo> infos; |
| 735 transport_channel_->GetStats(&infos); | 770 transport_channel_->GetStats(&infos); |
| 736 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); | 771 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); |
| 737 it != infos.end(); ++it) { | 772 it != infos.end(); ++it) { |
| 738 if (it->best_connection) { | 773 if (it->best_connection) { |
| 739 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() | 774 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() |
| 740 << "->" << it->remote_candidate.ToSensitiveString(); | 775 << "->" << it->remote_candidate.ToSensitiveString(); |
| 741 break; | 776 break; |
| 742 } | 777 } |
| 743 } | 778 } |
| 744 | 779 |
| 745 // If we're doing DTLS-SRTP, now is the time. | 780 // If we're doing DTLS-SRTP, now is the time. |
| 746 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { | 781 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { |
| 747 if (!SetupDtlsSrtp(false)) { | 782 if (!SetupDtlsSrtp(false)) { |
| 748 SignalDtlsSetupFailure(this, false); | 783 SignalDtlsSetupFailure_w(false); |
| 749 return; | 784 return; |
| 750 } | 785 } |
| 751 | 786 |
| 752 if (rtcp_transport_channel_) { | 787 if (rtcp_transport_channel_) { |
| 753 if (!SetupDtlsSrtp(true)) { | 788 if (!SetupDtlsSrtp(true)) { |
| 754 SignalDtlsSetupFailure(this, true); | 789 SignalDtlsSetupFailure_w(true); |
| 755 return; | 790 return; |
| 756 } | 791 } |
| 757 } | 792 } |
| 758 } | 793 } |
| 759 | 794 |
| 760 was_ever_writable_ = true; | 795 was_ever_writable_ = true; |
| 761 writable_ = true; | 796 writable_ = true; |
| 762 ChangeState(); | 797 ChangeState(); |
| 763 } | 798 } |
| 764 | 799 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 787 | 822 |
| 788 bool BaseChannel::ShouldSetupDtlsSrtp() const { | 823 bool BaseChannel::ShouldSetupDtlsSrtp() const { |
| 789 return true; | 824 return true; |
| 790 } | 825 } |
| 791 | 826 |
| 792 // This function returns true if either DTLS-SRTP is not in use | 827 // This function returns true if either DTLS-SRTP is not in use |
| 793 // *or* DTLS-SRTP is successfully set up. | 828 // *or* DTLS-SRTP is successfully set up. |
| 794 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { | 829 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { |
| 795 bool ret = false; | 830 bool ret = false; |
| 796 | 831 |
| 797 TransportChannel *channel = rtcp_channel ? | 832 TransportChannel* channel = |
| 798 rtcp_transport_channel_ : transport_channel_; | 833 rtcp_channel ? rtcp_transport_channel_ : transport_channel_; |
| 799 | 834 |
| 800 // No DTLS | 835 // No DTLS |
| 801 if (!channel->IsDtlsActive()) | 836 if (!channel->IsDtlsActive()) |
| 802 return true; | 837 return true; |
| 803 | 838 |
| 804 std::string selected_cipher; | 839 std::string selected_cipher; |
| 805 | 840 |
| 806 if (!channel->GetSrtpCipher(&selected_cipher)) { | 841 if (!channel->GetSrtpCipher(&selected_cipher)) { |
| 807 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher"; | 842 LOG(LS_ERROR) << "No DTLS-SRTP selected cipher"; |
| 808 return false; | 843 return false; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 dtls_keyed_ = true; | 918 dtls_keyed_ = true; |
| 884 | 919 |
| 885 return ret; | 920 return ret; |
| 886 } | 921 } |
| 887 | 922 |
| 888 void BaseChannel::ChannelNotWritable_w() { | 923 void BaseChannel::ChannelNotWritable_w() { |
| 889 ASSERT(worker_thread_ == rtc::Thread::Current()); | 924 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 890 if (!writable_) | 925 if (!writable_) |
| 891 return; | 926 return; |
| 892 | 927 |
| 893 LOG(LS_INFO) << "Channel socket not writable (" | 928 LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")"; |
| 894 << transport_channel_->content_name() << ", " | |
| 895 << transport_channel_->component() << ")"; | |
| 896 writable_ = false; | 929 writable_ = false; |
| 897 ChangeState(); | 930 ChangeState(); |
| 898 } | 931 } |
| 899 | 932 |
| 900 // |dtls| will be set to true if DTLS is active for transport channel and | 933 // |dtls| will be set to true if DTLS is active for transport channel and |
| 901 // crypto is empty. | 934 // crypto is empty. |
| 902 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, | 935 bool BaseChannel::CheckSrtpConfig(const std::vector<CryptoParams>& cryptos, |
| 903 bool* dtls, | 936 bool* dtls, |
| 904 std::string* error_desc) { | 937 std::string* error_desc) { |
| 905 *dtls = transport_channel_->IsDtlsActive(); | 938 *dtls = transport_channel_->IsDtlsActive(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 994 } | 1027 } |
| 995 | 1028 |
| 996 void BaseChannel::ActivateRtcpMux() { | 1029 void BaseChannel::ActivateRtcpMux() { |
| 997 worker_thread_->Invoke<void>(Bind( | 1030 worker_thread_->Invoke<void>(Bind( |
| 998 &BaseChannel::ActivateRtcpMux_w, this)); | 1031 &BaseChannel::ActivateRtcpMux_w, this)); |
| 999 } | 1032 } |
| 1000 | 1033 |
| 1001 void BaseChannel::ActivateRtcpMux_w() { | 1034 void BaseChannel::ActivateRtcpMux_w() { |
| 1002 if (!rtcp_mux_filter_.IsActive()) { | 1035 if (!rtcp_mux_filter_.IsActive()) { |
| 1003 rtcp_mux_filter_.SetActive(); | 1036 rtcp_mux_filter_.SetActive(); |
| 1004 set_rtcp_transport_channel(NULL); | 1037 set_rtcp_transport_channel(nullptr); |
| 1005 } | 1038 } |
| 1006 } | 1039 } |
| 1007 | 1040 |
| 1008 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, | 1041 bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action, |
| 1009 ContentSource src, | 1042 ContentSource src, |
| 1010 std::string* error_desc) { | 1043 std::string* error_desc) { |
| 1011 bool ret = false; | 1044 bool ret = false; |
| 1012 switch (action) { | 1045 switch (action) { |
| 1013 case CA_OFFER: | 1046 case CA_OFFER: |
| 1014 ret = rtcp_mux_filter_.SetOffer(enable, src); | 1047 ret = rtcp_mux_filter_.SetOffer(enable, src); |
| 1015 break; | 1048 break; |
| 1016 case CA_PRANSWER: | 1049 case CA_PRANSWER: |
| 1017 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); | 1050 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); |
| 1018 break; | 1051 break; |
| 1019 case CA_ANSWER: | 1052 case CA_ANSWER: |
| 1020 ret = rtcp_mux_filter_.SetAnswer(enable, src); | 1053 ret = rtcp_mux_filter_.SetAnswer(enable, src); |
| 1021 if (ret && rtcp_mux_filter_.IsActive()) { | 1054 if (ret && rtcp_mux_filter_.IsActive()) { |
| 1022 // We activated RTCP mux, close down the RTCP transport. | 1055 // We activated RTCP mux, close down the RTCP transport. |
| 1023 set_rtcp_transport_channel(NULL); | 1056 LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() |
| 1057 << " by destroying RTCP transport channel for " | |
| 1058 << transport_name(); | |
| 1059 set_rtcp_transport_channel(nullptr); | |
| 1024 } | 1060 } |
| 1025 break; | 1061 break; |
| 1026 case CA_UPDATE: | 1062 case CA_UPDATE: |
| 1027 // No RTCP mux info. | 1063 // No RTCP mux info. |
| 1028 ret = true; | 1064 ret = true; |
| 1029 break; | 1065 break; |
| 1030 default: | 1066 default: |
| 1031 break; | 1067 break; |
| 1032 } | 1068 } |
| 1033 if (!ret) { | 1069 if (!ret) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1283 worker_thread_->Clear(this, MSG_RTCPPACKET, &rtcp_messages); | 1319 worker_thread_->Clear(this, MSG_RTCPPACKET, &rtcp_messages); |
| 1284 for (rtc::MessageList::iterator it = rtcp_messages.begin(); | 1320 for (rtc::MessageList::iterator it = rtcp_messages.begin(); |
| 1285 it != rtcp_messages.end(); ++it) { | 1321 it != rtcp_messages.end(); ++it) { |
| 1286 worker_thread_->Send(this, MSG_RTCPPACKET, it->pdata); | 1322 worker_thread_->Send(this, MSG_RTCPPACKET, it->pdata); |
| 1287 } | 1323 } |
| 1288 } | 1324 } |
| 1289 | 1325 |
| 1290 VoiceChannel::VoiceChannel(rtc::Thread* thread, | 1326 VoiceChannel::VoiceChannel(rtc::Thread* thread, |
| 1291 MediaEngineInterface* media_engine, | 1327 MediaEngineInterface* media_engine, |
| 1292 VoiceMediaChannel* media_channel, | 1328 VoiceMediaChannel* media_channel, |
| 1293 BaseSession* session, | 1329 TransportController* transport_controller, |
| 1294 const std::string& content_name, | 1330 const std::string& content_name, |
| 1295 bool rtcp) | 1331 bool rtcp) |
| 1296 : BaseChannel(thread, media_channel, session, content_name, | 1332 : BaseChannel(thread, |
| 1333 media_channel, | |
| 1334 transport_controller, | |
| 1335 content_name, | |
| 1297 rtcp), | 1336 rtcp), |
| 1298 media_engine_(media_engine), | 1337 media_engine_(media_engine), |
| 1299 received_media_(false) { | 1338 received_media_(false) { |
| 1300 } | 1339 } |
| 1301 | 1340 |
| 1302 VoiceChannel::~VoiceChannel() { | 1341 VoiceChannel::~VoiceChannel() { |
| 1303 StopAudioMonitor(); | 1342 StopAudioMonitor(); |
| 1304 StopMediaMonitor(); | 1343 StopMediaMonitor(); |
| 1305 // this can't be done in the base class, since it calls a virtual | 1344 // this can't be done in the base class, since it calls a virtual |
| 1306 DisableMedia_w(); | 1345 DisableMedia_w(); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1678 break; | 1717 break; |
| 1679 } | 1718 } |
| 1680 } | 1719 } |
| 1681 | 1720 |
| 1682 void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { | 1721 void VoiceChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { |
| 1683 GetSupportedAudioCryptoSuites(ciphers); | 1722 GetSupportedAudioCryptoSuites(ciphers); |
| 1684 } | 1723 } |
| 1685 | 1724 |
| 1686 VideoChannel::VideoChannel(rtc::Thread* thread, | 1725 VideoChannel::VideoChannel(rtc::Thread* thread, |
| 1687 VideoMediaChannel* media_channel, | 1726 VideoMediaChannel* media_channel, |
| 1688 BaseSession* session, | 1727 TransportController* transport_controller, |
| 1689 const std::string& content_name, | 1728 const std::string& content_name, |
| 1690 bool rtcp) | 1729 bool rtcp) |
| 1691 : BaseChannel(thread, media_channel, session, content_name, | 1730 : BaseChannel(thread, |
| 1731 media_channel, | |
| 1732 transport_controller, | |
| 1733 content_name, | |
| 1692 rtcp), | 1734 rtcp), |
| 1693 renderer_(NULL), | 1735 renderer_(NULL), |
| 1694 previous_we_(rtc::WE_CLOSE) { | 1736 previous_we_(rtc::WE_CLOSE) { |
| 1695 } | 1737 } |
| 1696 | 1738 |
| 1697 bool VideoChannel::Init() { | 1739 bool VideoChannel::Init() { |
| 1698 if (!BaseChannel::Init()) { | 1740 if (!BaseChannel::Init()) { |
| 1699 return false; | 1741 return false; |
| 1700 } | 1742 } |
| 1701 media_channel()->SignalMediaError.connect( | 1743 media_channel()->SignalMediaError.connect( |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2116 } | 2158 } |
| 2117 } | 2159 } |
| 2118 | 2160 |
| 2119 | 2161 |
| 2120 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { | 2162 void VideoChannel::GetSrtpCiphers(std::vector<std::string>* ciphers) const { |
| 2121 GetSupportedVideoCryptoSuites(ciphers); | 2163 GetSupportedVideoCryptoSuites(ciphers); |
| 2122 } | 2164 } |
| 2123 | 2165 |
| 2124 DataChannel::DataChannel(rtc::Thread* thread, | 2166 DataChannel::DataChannel(rtc::Thread* thread, |
| 2125 DataMediaChannel* media_channel, | 2167 DataMediaChannel* media_channel, |
| 2126 BaseSession* session, | 2168 TransportController* transport_controller, |
| 2127 const std::string& content_name, | 2169 const std::string& content_name, |
| 2128 bool rtcp) | 2170 bool rtcp) |
| 2129 : BaseChannel(thread, media_channel, session, content_name, rtcp), | 2171 : BaseChannel(thread, |
| 2172 media_channel, | |
| 2173 transport_controller, | |
| 2174 content_name, | |
| 2175 rtcp), | |
| 2130 data_channel_type_(cricket::DCT_NONE), | 2176 data_channel_type_(cricket::DCT_NONE), |
| 2131 ready_to_send_data_(false) { | 2177 ready_to_send_data_(false) { |
| 2132 } | 2178 } |
| 2133 | 2179 |
| 2134 DataChannel::~DataChannel() { | 2180 DataChannel::~DataChannel() { |
| 2135 StopMediaMonitor(); | 2181 StopMediaMonitor(); |
| 2136 // this can't be done in the base class, since it calls a virtual | 2182 // this can't be done in the base class, since it calls a virtual |
| 2137 DisableMedia_w(); | 2183 DisableMedia_w(); |
| 2138 | 2184 |
| 2139 Deinit(); | 2185 Deinit(); |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2473 return (data_channel_type_ == DCT_RTP); | 2519 return (data_channel_type_ == DCT_RTP); |
| 2474 } | 2520 } |
| 2475 | 2521 |
| 2476 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2522 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
| 2477 rtc::TypedMessageData<uint32>* message = | 2523 rtc::TypedMessageData<uint32>* message = |
| 2478 new rtc::TypedMessageData<uint32>(sid); | 2524 new rtc::TypedMessageData<uint32>(sid); |
| 2479 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2525 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
| 2480 } | 2526 } |
| 2481 | 2527 |
| 2482 } // namespace cricket | 2528 } // namespace cricket |
| OLD | NEW |