Index: webrtc/p2p/rawudp/rawudptransportchannel.cc |
diff --git a/webrtc/p2p/rawudp/rawudptransportchannel.cc b/webrtc/p2p/rawudp/rawudptransportchannel.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..20835c2d15e30f5a5515fa1dcb1f5ba9c9e479fa |
--- /dev/null |
+++ b/webrtc/p2p/rawudp/rawudptransportchannel.cc |
@@ -0,0 +1,224 @@ |
+/* |
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#include "webrtc/p2p/rawudp/rawudptransportchannel.h" |
+ |
+#include <string> |
+ |
+#include "webrtc/base/asyncudpsocket.h" |
+#include "webrtc/base/logging.h" |
+#include "webrtc/base/physicalsocketserver.h" |
+#include "webrtc/base/socketaddress.h" |
+#include "webrtc/base/thread.h" |
+ |
+ |
+namespace cricket { |
+ |
+RawUdpTransportChannel::RawUdpTransportChannel( |
+ const std::string& transport_name, |
+ int component) |
+ : RawUdpTransportChannel(transport_name, |
+ component, |
+ rtc::Thread::Current(), |
+ rtc::Thread::Current()->socketserver()) {} |
+ |
+RawUdpTransportChannel::RawUdpTransportChannel( |
+ const std::string& transport_name, |
+ int component, |
+ rtc::Thread* network_thread, |
+ rtc::SocketServer* ss) |
+ : TransportChannelImpl(transport_name, component), |
+ tch_state_(STATE_INIT), |
+ gathering_state_(kIceGatheringNew), |
+ local_candidate_(), |
+ remote_candidate_() { |
sprang_webrtc
2016/10/07 09:56:21
We usually omit default constructors in the initia
johan
2016/10/07 12:24:26
Acknowledged.
|
+ network_thread_ = network_thread; |
sprang_webrtc
2016/10/07 09:56:21
Why not in the initializer list?
johan
2016/10/07 12:24:26
Leftover from a different implementation approach.
|
+} |
+ |
+RawUdpTransportChannel::~RawUdpTransportChannel() { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
sprang_webrtc
2016/10/07 09:56:21
Please use ThreadChecker utility, here and elsewhe
|
+} |
+ |
+void RawUdpTransportChannel::OnSocketReadPacket( |
+ rtc::AsyncPacketSocket* socket, |
+ const char* data, |
+ size_t len, |
+ const rtc::SocketAddress& remote_addr, |
+ const rtc::PacketTime& packet_time, |
+ bool is_rtcp) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ // serialisation of processing RTP and RTCP socket is implicit done by event |
+ // loop. |
+ SignalReadPacket(this, data, len, packet_time, 0); |
+} |
+ |
+void RawUdpTransportChannel::OnRtpSocketReadPacket( |
+ rtc::AsyncPacketSocket* socket, |
+ const char* data, |
+ size_t len, |
+ const rtc::SocketAddress& remote_addr, |
+ const rtc::PacketTime& packet_time) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ // TODO(johan) check, if remote_addr is valid and legit |
+ LOG(LS_VERBOSE) << "received rtp packet"; |
sprang_webrtc
2016/10/07 09:56:21
This looks extremely verbose. Will it be useful ou
johan
2016/10/07 12:24:26
Only useful for debug. Removing it.
|
+ OnSocketReadPacket(socket, data, len, remote_addr, packet_time, |
+ false /*rtcp*/); |
+} |
+ |
+void RawUdpTransportChannel::OnRtcpSocketReadPacket( |
+ rtc::AsyncPacketSocket* socket, |
+ const char* data, |
+ size_t len, |
+ const rtc::SocketAddress& remote_addr, |
+ const rtc::PacketTime& packet_time) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ // TODO(johan) check, if remote_addr is valid and legit |
+ LOG(LS_VERBOSE) << "received rtcp packet"; |
+ OnSocketReadPacket(socket, data, len, remote_addr, packet_time, |
+ true /*rtcp*/); |
+} |
+ |
+int RawUdpTransportChannel::SendPacket(const char* data, |
+ size_t len, |
+ const rtc::PacketOptions& options, |
+ int flags) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ int32_t is_rtcp = 0; |
+ // TODO(johan): add logic to send rtcp packets over rtcp socket |
+ int result = -1; |
+ if (is_rtcp) { |
sprang_webrtc
2016/10/07 09:56:21
Just do
if (!is_rtcp) { result = ... }
Add the if/
johan
2016/10/07 12:24:25
Acknowledged.
|
+ } else { |
+ result = rtp_socket_->SendTo((const void*)data, len, remote_addr_, options); |
+ } |
+ LOG(LS_VERBOSE) << "SendPacket() " << result; |
+ return result; |
+} |
+ |
+bool RawUdpTransportChannel::TryAllocateSockets() { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ const uint16_t maxTry = 100; |
sprang_webrtc
2016/10/07 09:56:21
I'd do
static constexpr uint16_t kMaxTries = 100;
johan
2016/10/07 12:24:25
Acknowledged.
|
+ rtc::SocketAddress rtp_socket_addr("0.0.0.0", 0); |
+ rtc::SocketAddress rtcp_socket_addr("0.0.0.0", 1); |
+ // TODO(johan) allocate sockets only once, and loop over |
+ // rtc::AsyncSocketAdapter::bind() |
+ for (uint16_t count = 0; count < maxTry; ++count) { |
+ uint16_t rtpport = 2000 + (2 * count); |
sprang_webrtc
2016/10/07 09:56:21
Why 2000? Named constant?
johan
2016/10/07 12:24:26
Changing this to a constant. Will probably change
|
+ rtp_socket_addr.SetPort(rtpport); |
+ rtp_socket_.reset(rtc::AsyncUDPSocket::Create( |
+ network_thread_->socketserver(), rtp_socket_addr)); |
+ if (!rtp_socket_) { |
+ continue; |
+ } |
+ rtcp_socket_addr.SetPort(rtpport + 1); |
+ rtcp_socket_.reset(rtc::AsyncUDPSocket::Create( |
+ network_thread_->socketserver(), rtcp_socket_addr)); |
+ if (rtp_socket_ && rtcp_socket_) { |
+ LOG(INFO) << "Allocated Rtp socket with local port " << rtpport; |
+ rtp_socket_->SignalReadPacket.connect( |
+ this, &RawUdpTransportChannel::OnRtpSocketReadPacket); |
+ rtcp_socket_->SignalReadPacket.connect( |
+ this, &RawUdpTransportChannel::OnRtcpSocketReadPacket); |
+ local_candidate_.set_address(rtp_socket_addr); |
+ return true; |
+ } |
+ } |
+ rtp_socket_.reset(); |
+ rtcp_socket_.reset(); |
+ return false; |
+} |
+ |
+void RawUdpTransportChannel::MaybeStartGathering() { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ if (gathering_state_ != kIceGatheringNew) { |
+ LOG(INFO) << "candidates gathering already done, early return"; |
+ return; |
+ } |
+ SetGatheringState(kIceGatheringGathering); |
+ TryAllocateSockets(); |
+ SignalCandidateGathered(this, local_candidate_); |
+ SetGatheringState(kIceGatheringComplete); |
+} |
+ |
+void RawUdpTransportChannel::UpdateWritableState() { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ bool writable = true; |
+ if (!rtp_socket_) { |
+ writable = false; |
+ LOG(INFO) << "rtp_socket_ is false"; |
+ } |
+ if (!remote_addr_.IsComplete()) { |
+ writable = false; |
+ LOG(INFO) << "remote_addr_ not complete"; |
+ } |
+ if (gathering_state_ != kIceGatheringComplete) { |
+ writable = false; |
+ LOG(INFO) << "gathering_state_ " << gathering_state_; |
+ } |
+ set_writable(writable); |
+} |
+ |
+void RawUdpTransportChannel::AddRemoteCandidate(const Candidate& candidate) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ // TODO(johan) check for ipv4, other settings |
+ remote_candidate_ = candidate; |
+ remote_addr_ = candidate.address(); |
+ // TODO(johan) - only set STATE_COMPLETED if *both* local and remote addr are |
+ // set. Maybe use an rtc::Optional to indicate unset addr? |
+ SetTransportChannelState(STATE_COMPLETED); |
+ // TODO(johan) - set STATE_FAILED, if remote addr is invalid |
+ UpdateWritableState(); |
+} |
+ |
+IceGatheringState RawUdpTransportChannel::gathering_state() const { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ return gathering_state_; |
+} |
+ |
+bool RawUdpTransportChannel::SetRemoteAddrAndPorts(const char* ip_addr, |
+ int rtp_port) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ remote_addr_ = rtc::SocketAddress(ip_addr, rtp_port); |
+ return true; |
+} |
+ |
+TransportChannelState RawUdpTransportChannel::GetState() const { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ return tch_state_; |
+} |
+ |
+void RawUdpTransportChannel::SetGatheringState( |
+ IceGatheringState new_gathering_state) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ /* |
+ kIceGatheringNew = 0, |
+ kIceGatheringGathering, |
+ kIceGatheringComplete, |
+ */ |
sprang_webrtc
2016/10/07 09:56:21
Remove this comment
johan
2016/10/07 12:24:26
Acknowledged.
|
+ if (gathering_state_ != new_gathering_state) { |
+ gathering_state_ = new_gathering_state; |
+ SignalGatheringState(this); |
+ } |
+} |
+ |
+void RawUdpTransportChannel::SetTransportChannelState( |
+ TransportChannelState new_tch_state) { |
+ RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); |
+ /* |
+ STATE_INIT, |
+ STATE_CONNECTING, // Will enter this state once a connection is created |
+ STATE_COMPLETED, |
+ STATE_FAILED |
+ */ |
sprang_webrtc
2016/10/07 09:56:21
Remove this comment.
johan
2016/10/07 12:24:26
Acknowledged.
|
+ if (tch_state_ != new_tch_state) { |
+ tch_state_ = new_tch_state; |
+ SignalStateChanged(this); |
+ } |
+} |
+} // namespace cricket |