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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 enabled_(false), | 184 enabled_(false), |
185 writable_(false), | 185 writable_(false), |
186 rtp_ready_to_send_(false), | 186 rtp_ready_to_send_(false), |
187 rtcp_ready_to_send_(false), | 187 rtcp_ready_to_send_(false), |
188 was_ever_writable_(false), | 188 was_ever_writable_(false), |
189 local_content_direction_(MD_INACTIVE), | 189 local_content_direction_(MD_INACTIVE), |
190 remote_content_direction_(MD_INACTIVE), | 190 remote_content_direction_(MD_INACTIVE), |
191 has_received_packet_(false), | 191 has_received_packet_(false), |
192 dtls_keyed_(false), | 192 dtls_keyed_(false), |
193 secure_required_(false), | 193 secure_required_(false), |
194 rtp_abs_sendtime_extn_id_(-1) { | 194 rtp_abs_sendtime_extn_id_(-1), |
195 rtp_transport_sequence_number_extn_id_(-1) { | |
195 ASSERT(worker_thread_ == rtc::Thread::Current()); | 196 ASSERT(worker_thread_ == rtc::Thread::Current()); |
196 LOG(LS_INFO) << "Created channel for " << content_name; | 197 LOG(LS_INFO) << "Created channel for " << content_name; |
197 } | 198 } |
198 | 199 |
199 BaseChannel::~BaseChannel() { | 200 BaseChannel::~BaseChannel() { |
200 ASSERT(worker_thread_ == rtc::Thread::Current()); | 201 ASSERT(worker_thread_ == rtc::Thread::Current()); |
201 Deinit(); | 202 Deinit(); |
202 StopConnectionMonitor(); | 203 StopConnectionMonitor(); |
203 FlushRtcpMessages(); // Send any outstanding RTCP packets. | 204 FlushRtcpMessages(); // Send any outstanding RTCP packets. |
204 worker_thread_->Clear(this); // eats any outstanding messages or packets | 205 worker_thread_->Clear(this); // eats any outstanding messages or packets |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 // setting new channel | 337 // setting new channel |
337 UpdateWritableState_w(); | 338 UpdateWritableState_w(); |
338 SetReadyToSend(true, new_tc && new_tc->writable()); | 339 SetReadyToSend(true, new_tc && new_tc->writable()); |
339 } | 340 } |
340 | 341 |
341 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { | 342 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
342 ASSERT(worker_thread_ == rtc::Thread::Current()); | 343 ASSERT(worker_thread_ == rtc::Thread::Current()); |
343 | 344 |
344 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 345 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
345 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); | 346 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
347 tc->SignalSentPacket.connect(this, &BaseChannel::OnPacketSent); | |
346 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | 348 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
347 } | 349 } |
348 | 350 |
349 void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { | 351 void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { |
350 ASSERT(worker_thread_ == rtc::Thread::Current()); | 352 ASSERT(worker_thread_ == rtc::Thread::Current()); |
351 | 353 |
352 tc->SignalWritableState.disconnect(this); | 354 tc->SignalWritableState.disconnect(this); |
353 tc->SignalReadPacket.disconnect(this); | 355 tc->SignalReadPacket.disconnect(this); |
354 tc->SignalReadyToSend.disconnect(this); | 356 tc->SignalReadyToSend.disconnect(this); |
355 } | 357 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine | 472 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine |
471 ASSERT(worker_thread_ == rtc::Thread::Current()); | 473 ASSERT(worker_thread_ == rtc::Thread::Current()); |
472 | 474 |
473 // When using RTCP multiplexing we might get RTCP packets on the RTP | 475 // When using RTCP multiplexing we might get RTCP packets on the RTP |
474 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. | 476 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. |
475 bool rtcp = PacketIsRtcp(channel, data, len); | 477 bool rtcp = PacketIsRtcp(channel, data, len); |
476 rtc::Buffer packet(data, len); | 478 rtc::Buffer packet(data, len); |
477 HandlePacket(rtcp, &packet, packet_time); | 479 HandlePacket(rtcp, &packet, packet_time); |
478 } | 480 } |
479 | 481 |
482 void BaseChannel::OnPacketSent(TransportChannel* channel, | |
483 const rtc::SentPacket& packet_sent) { | |
484 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | |
485 if (channel == transport_channel_) { | |
486 media_channel_->OnPacketSent(packet_sent); | |
pthatcher1
2015/09/25 23:24:57
This means that all 3 channels (audio, video, and
stefan-webrtc
2015/09/28 12:10:49
That would be nicer. I'll look into it.
| |
487 } | |
488 } | |
489 | |
480 void BaseChannel::OnReadyToSend(TransportChannel* channel) { | 490 void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
481 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 491 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
482 SetReadyToSend(channel == rtcp_transport_channel_, true); | 492 SetReadyToSend(channel == rtcp_transport_channel_, true); |
483 } | 493 } |
484 | 494 |
485 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { | 495 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
486 if (rtcp) { | 496 if (rtcp) { |
487 rtcp_ready_to_send_ = ready; | 497 rtcp_ready_to_send_ = ready; |
488 } else { | 498 } else { |
489 rtp_ready_to_send_ = ready; | 499 rtp_ready_to_send_ = ready; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 // inside libsrtp for a RTP packet. A external HMAC module will be writing | 564 // inside libsrtp for a RTP packet. A external HMAC module will be writing |
555 // a fake HMAC value. This is ONLY done for a RTP packet. | 565 // a fake HMAC value. This is ONLY done for a RTP packet. |
556 // Socket layer will update rtp sendtime extension header if present in | 566 // Socket layer will update rtp sendtime extension header if present in |
557 // packet with current time before updating the HMAC. | 567 // packet with current time before updating the HMAC. |
558 #if !defined(ENABLE_EXTERNAL_AUTH) | 568 #if !defined(ENABLE_EXTERNAL_AUTH) |
559 res = srtp_filter_.ProtectRtp( | 569 res = srtp_filter_.ProtectRtp( |
560 data, len, static_cast<int>(packet->capacity()), &len); | 570 data, len, static_cast<int>(packet->capacity()), &len); |
561 #else | 571 #else |
562 options.packet_time_params.rtp_sendtime_extension_id = | 572 options.packet_time_params.rtp_sendtime_extension_id = |
563 rtp_abs_sendtime_extn_id_; | 573 rtp_abs_sendtime_extn_id_; |
574 options.transport_sequence_number = | |
575 ParseTransportSequenceNumberHeaderExtension(data, len); | |
pthatcher1
2015/09/25 23:24:57
I really think is the wrong place for this. It wo
stefan-webrtc
2015/09/28 12:10:50
Yes, I definitely agree that it would make more se
stefan-webrtc
2015/10/02 13:29:12
Done.
| |
564 res = srtp_filter_.ProtectRtp( | 576 res = srtp_filter_.ProtectRtp( |
565 data, len, static_cast<int>(packet->capacity()), &len, | 577 data, len, static_cast<int>(packet->capacity()), &len, |
566 &options.packet_time_params.srtp_packet_index); | 578 &options.packet_time_params.srtp_packet_index); |
567 // If protection succeeds, let's get auth params from srtp. | 579 // If protection succeeds, let's get auth params from srtp. |
568 if (res) { | 580 if (res) { |
569 uint8* auth_key = NULL; | 581 uint8* auth_key = NULL; |
570 int key_len; | 582 int key_len; |
571 res = srtp_filter_.GetRtpAuthParams( | 583 res = srtp_filter_.GetRtpAuthParams( |
572 &auth_key, &key_len, &options.packet_time_params.srtp_auth_tag_len); | 584 &auth_key, &key_len, &options.packet_time_params.srtp_auth_tag_len); |
573 if (res) { | 585 if (res) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 if (ret != static_cast<int>(packet->size())) { | 630 if (ret != static_cast<int>(packet->size())) { |
619 if (channel->GetError() == EWOULDBLOCK) { | 631 if (channel->GetError() == EWOULDBLOCK) { |
620 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; | 632 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; |
621 SetReadyToSend(rtcp, false); | 633 SetReadyToSend(rtcp, false); |
622 } | 634 } |
623 return false; | 635 return false; |
624 } | 636 } |
625 return true; | 637 return true; |
626 } | 638 } |
627 | 639 |
640 int32_t BaseChannel::ParseTransportSequenceNumberHeaderExtension( | |
641 uint8_t* data, | |
642 size_t length) const { | |
643 // 0 1 2 3 | |
644 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
645 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
646 // |V=2|P|X| CC |M| PT | sequence number | | |
647 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
648 // | timestamp | | |
649 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
650 // | synchronization source (SSRC) identifier | | |
651 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
652 // | contributing source (CSRC) identifiers | | |
653 // | .... | | |
654 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
655 | |
656 // Return if extension bit is not set. | |
657 if (!(data[0] & 0x10)) { | |
658 return -1; | |
659 } | |
660 | |
661 size_t cc_count = data[0] & 0x0F; | |
662 const size_t kMinRtpHeaderLength = 12; | |
663 size_t header_length_without_extension = kMinRtpHeaderLength + 4 * cc_count; | |
664 | |
665 data += header_length_without_extension; | |
666 | |
667 // Getting extension profile ID and length. | |
668 uint16 profile_id = rtc::GetBE16(data); | |
669 // Length is in 32 bit words. | |
670 uint16 extension_length_in_32bits = rtc::GetBE16(data + 2); | |
671 size_t extension_length = extension_length_in_32bits * 4; | |
672 | |
673 const size_t kRtpExtensionHeaderLength = 4; | |
674 data += kRtpExtensionHeaderLength; // Moving past extension header. | |
675 | |
676 int32_t transport_sequence_number = -1; | |
677 // The transport sequence number is a one byte header extension. | |
678 if (profile_id == 0xBEDE) { // One byte extension header. | |
679 // 0 | |
680 // 0 1 2 3 4 5 6 7 | |
681 // +-+-+-+-+-+-+-+-+ | |
682 // | ID |length | | |
683 // +-+-+-+-+-+-+-+-+ | |
684 | |
685 // 0 1 2 3 | |
686 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
687 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
688 // | 0xBE | 0xDE | length=3 | | |
689 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
690 // | ID | L=0 | data | ID | L=1 | data... | |
691 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
692 // ...data | 0 (pad) | 0 (pad) | ID | L=3 | | |
693 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
694 // | data | | |
695 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
696 const uint8_t* extension_start = data; | |
697 const uint8_t* extension_end = extension_start + extension_length; | |
698 | |
699 while (data < extension_end) { | |
700 const int id = (*data & 0xF0) >> 4; | |
701 const size_t length = (*data & 0x0F) + 1; | |
702 const size_t kOneByteHeaderLength = 1; | |
703 if (data + kOneByteHeaderLength + length > extension_end) { | |
704 break; | |
705 } | |
706 // The 4-bit length is the number minus one of data bytes of this header | |
707 // extension element following the one-byte header. | |
708 if (id == rtp_transport_sequence_number_extn_id_) { | |
709 transport_sequence_number = rtc::GetBE24(data + kOneByteHeaderLength); | |
710 break; | |
711 } | |
712 data += kOneByteHeaderLength + length; | |
713 // Counting padding bytes. | |
714 while ((data < extension_end) && (*data == 0)) { | |
715 ++data; | |
716 } | |
717 } | |
718 } | |
719 return transport_sequence_number; | |
720 } | |
721 | |
628 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { | 722 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { |
629 // Protect ourselves against crazy data. | 723 // Protect ourselves against crazy data. |
630 if (!ValidPacket(rtcp, packet)) { | 724 if (!ValidPacket(rtcp, packet)) { |
631 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " | 725 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " |
632 << PacketType(rtcp) | 726 << PacketType(rtcp) |
633 << " packet: wrong size=" << packet->size(); | 727 << " packet: wrong size=" << packet->size(); |
634 return false; | 728 return false; |
635 } | 729 } |
636 | 730 |
637 // Bundle filter handles both rtp and rtcp packets. | 731 // Bundle filter handles both rtp and rtcp packets. |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1232 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); | 1326 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); |
1233 SafeSetError(desc.str(), error_desc); | 1327 SafeSetError(desc.str(), error_desc); |
1234 ret = false; | 1328 ret = false; |
1235 } | 1329 } |
1236 } | 1330 } |
1237 } | 1331 } |
1238 remote_streams_ = streams; | 1332 remote_streams_ = streams; |
1239 return ret; | 1333 return ret; |
1240 } | 1334 } |
1241 | 1335 |
1242 void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( | 1336 void BaseChannel::MaybeCacheRtpHeaderExtensions( |
1243 const std::vector<RtpHeaderExtension>& extensions) { | 1337 const std::vector<RtpHeaderExtension>& extensions) { |
1244 const RtpHeaderExtension* send_time_extension = | 1338 const RtpHeaderExtension* send_time_extension = |
1245 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); | 1339 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
1246 rtp_abs_sendtime_extn_id_ = | 1340 rtp_abs_sendtime_extn_id_ = |
1247 send_time_extension ? send_time_extension->id : -1; | 1341 send_time_extension ? send_time_extension->id : -1; |
1342 | |
1343 const RtpHeaderExtension* transport_sequence_number = FindHeaderExtension( | |
1344 extensions, kRtpTransportSequenceNumberHeaderExtension); | |
1345 rtp_transport_sequence_number_extn_id_ = | |
1346 transport_sequence_number ? transport_sequence_number->id : -1; | |
1248 } | 1347 } |
1249 | 1348 |
1250 void BaseChannel::OnMessage(rtc::Message *pmsg) { | 1349 void BaseChannel::OnMessage(rtc::Message *pmsg) { |
1251 switch (pmsg->message_id) { | 1350 switch (pmsg->message_id) { |
1252 case MSG_RTPPACKET: | 1351 case MSG_RTPPACKET: |
1253 case MSG_RTCPPACKET: { | 1352 case MSG_RTCPPACKET: { |
1254 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata); | 1353 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata); |
1255 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet, data->dscp); | 1354 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet, data->dscp); |
1256 delete data; // because it is Posted | 1355 delete data; // because it is Posted |
1257 break; | 1356 break; |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1531 // TODO(pthatcher): Move remote streams into AudioRecvParameters, | 1630 // TODO(pthatcher): Move remote streams into AudioRecvParameters, |
1532 // and only give it to the media channel once we have a local | 1631 // and only give it to the media channel once we have a local |
1533 // description too (without a local description, we won't be able to | 1632 // description too (without a local description, we won't be able to |
1534 // recv them anyway). | 1633 // recv them anyway). |
1535 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) { | 1634 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) { |
1536 SafeSetError("Failed to set remote audio description streams.", error_desc); | 1635 SafeSetError("Failed to set remote audio description streams.", error_desc); |
1537 return false; | 1636 return false; |
1538 } | 1637 } |
1539 | 1638 |
1540 if (audio->rtp_header_extensions_set()) { | 1639 if (audio->rtp_header_extensions_set()) { |
1541 MaybeCacheRtpAbsSendTimeHeaderExtension(audio->rtp_header_extensions()); | 1640 MaybeCacheRtpHeaderExtensions(audio->rtp_header_extensions()); |
1542 } | 1641 } |
1543 | 1642 |
1544 set_remote_content_direction(content->direction()); | 1643 set_remote_content_direction(content->direction()); |
1545 ChangeState(); | 1644 ChangeState(); |
1546 return true; | 1645 return true; |
1547 } | 1646 } |
1548 | 1647 |
1549 void VoiceChannel::HandleEarlyMediaTimeout() { | 1648 void VoiceChannel::HandleEarlyMediaTimeout() { |
1550 // This occurs on the main thread, not the worker thread. | 1649 // This occurs on the main thread, not the worker thread. |
1551 if (!received_media_) { | 1650 if (!received_media_) { |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1857 // TODO(pthatcher): Move remote streams into VideoRecvParameters, | 1956 // TODO(pthatcher): Move remote streams into VideoRecvParameters, |
1858 // and only give it to the media channel once we have a local | 1957 // and only give it to the media channel once we have a local |
1859 // description too (without a local description, we won't be able to | 1958 // description too (without a local description, we won't be able to |
1860 // recv them anyway). | 1959 // recv them anyway). |
1861 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) { | 1960 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) { |
1862 SafeSetError("Failed to set remote video description streams.", error_desc); | 1961 SafeSetError("Failed to set remote video description streams.", error_desc); |
1863 return false; | 1962 return false; |
1864 } | 1963 } |
1865 | 1964 |
1866 if (video->rtp_header_extensions_set()) { | 1965 if (video->rtp_header_extensions_set()) { |
1867 MaybeCacheRtpAbsSendTimeHeaderExtension(video->rtp_header_extensions()); | 1966 MaybeCacheRtpHeaderExtensions(video->rtp_header_extensions()); |
1868 } | 1967 } |
1869 | 1968 |
1870 set_remote_content_direction(content->direction()); | 1969 set_remote_content_direction(content->direction()); |
1871 ChangeState(); | 1970 ChangeState(); |
1872 return true; | 1971 return true; |
1873 } | 1972 } |
1874 | 1973 |
1875 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { | 1974 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { |
1876 bool ret = true; | 1975 bool ret = true; |
1877 // Set the send format for each of the local streams. If the view request | 1976 // Set the send format for each of the local streams. If the view request |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2403 return (data_channel_type_ == DCT_RTP); | 2502 return (data_channel_type_ == DCT_RTP); |
2404 } | 2503 } |
2405 | 2504 |
2406 void DataChannel::OnStreamClosedRemotely(uint32 sid) { | 2505 void DataChannel::OnStreamClosedRemotely(uint32 sid) { |
2407 rtc::TypedMessageData<uint32>* message = | 2506 rtc::TypedMessageData<uint32>* message = |
2408 new rtc::TypedMessageData<uint32>(sid); | 2507 new rtc::TypedMessageData<uint32>(sid); |
2409 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2508 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
2410 } | 2509 } |
2411 | 2510 |
2412 } // namespace cricket | 2511 } // namespace cricket |
OLD | NEW |