OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/p2p/rawudp/rawudptransportchannel.h" | |
12 | |
13 #include <string> | |
14 | |
15 #include "webrtc/base/asyncudpsocket.h" | |
16 #include "webrtc/base/logging.h" | |
17 #include "webrtc/base/physicalsocketserver.h" | |
18 #include "webrtc/base/socketaddress.h" | |
19 #include "webrtc/base/thread.h" | |
20 | |
21 | |
22 namespace cricket { | |
23 | |
24 RawUdpTransportChannel::RawUdpTransportChannel( | |
25 const std::string& transport_name, | |
26 int component) | |
27 : RawUdpTransportChannel(transport_name, | |
28 component, | |
29 rtc::Thread::Current(), | |
30 rtc::Thread::Current()->socketserver()) {} | |
31 | |
32 RawUdpTransportChannel::RawUdpTransportChannel( | |
33 const std::string& transport_name, | |
34 int component, | |
35 rtc::Thread* network_thread, | |
36 rtc::SocketServer* ss) | |
37 : TransportChannelImpl(transport_name, component), | |
38 tch_state_(STATE_INIT), | |
39 gathering_state_(kIceGatheringNew), | |
40 local_candidate_(), | |
41 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.
| |
42 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.
| |
43 } | |
44 | |
45 RawUdpTransportChannel::~RawUdpTransportChannel() { | |
46 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
sprang_webrtc
2016/10/07 09:56:21
Please use ThreadChecker utility, here and elsewhe
| |
47 } | |
48 | |
49 void RawUdpTransportChannel::OnSocketReadPacket( | |
50 rtc::AsyncPacketSocket* socket, | |
51 const char* data, | |
52 size_t len, | |
53 const rtc::SocketAddress& remote_addr, | |
54 const rtc::PacketTime& packet_time, | |
55 bool is_rtcp) { | |
56 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
57 // serialisation of processing RTP and RTCP socket is implicit done by event | |
58 // loop. | |
59 SignalReadPacket(this, data, len, packet_time, 0); | |
60 } | |
61 | |
62 void RawUdpTransportChannel::OnRtpSocketReadPacket( | |
63 rtc::AsyncPacketSocket* socket, | |
64 const char* data, | |
65 size_t len, | |
66 const rtc::SocketAddress& remote_addr, | |
67 const rtc::PacketTime& packet_time) { | |
68 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
69 // TODO(johan) check, if remote_addr is valid and legit | |
70 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.
| |
71 OnSocketReadPacket(socket, data, len, remote_addr, packet_time, | |
72 false /*rtcp*/); | |
73 } | |
74 | |
75 void RawUdpTransportChannel::OnRtcpSocketReadPacket( | |
76 rtc::AsyncPacketSocket* socket, | |
77 const char* data, | |
78 size_t len, | |
79 const rtc::SocketAddress& remote_addr, | |
80 const rtc::PacketTime& packet_time) { | |
81 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
82 // TODO(johan) check, if remote_addr is valid and legit | |
83 LOG(LS_VERBOSE) << "received rtcp packet"; | |
84 OnSocketReadPacket(socket, data, len, remote_addr, packet_time, | |
85 true /*rtcp*/); | |
86 } | |
87 | |
88 int RawUdpTransportChannel::SendPacket(const char* data, | |
89 size_t len, | |
90 const rtc::PacketOptions& options, | |
91 int flags) { | |
92 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
93 int32_t is_rtcp = 0; | |
94 // TODO(johan): add logic to send rtcp packets over rtcp socket | |
95 int result = -1; | |
96 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.
| |
97 } else { | |
98 result = rtp_socket_->SendTo((const void*)data, len, remote_addr_, options); | |
99 } | |
100 LOG(LS_VERBOSE) << "SendPacket() " << result; | |
101 return result; | |
102 } | |
103 | |
104 bool RawUdpTransportChannel::TryAllocateSockets() { | |
105 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
106 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.
| |
107 rtc::SocketAddress rtp_socket_addr("0.0.0.0", 0); | |
108 rtc::SocketAddress rtcp_socket_addr("0.0.0.0", 1); | |
109 // TODO(johan) allocate sockets only once, and loop over | |
110 // rtc::AsyncSocketAdapter::bind() | |
111 for (uint16_t count = 0; count < maxTry; ++count) { | |
112 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
| |
113 rtp_socket_addr.SetPort(rtpport); | |
114 rtp_socket_.reset(rtc::AsyncUDPSocket::Create( | |
115 network_thread_->socketserver(), rtp_socket_addr)); | |
116 if (!rtp_socket_) { | |
117 continue; | |
118 } | |
119 rtcp_socket_addr.SetPort(rtpport + 1); | |
120 rtcp_socket_.reset(rtc::AsyncUDPSocket::Create( | |
121 network_thread_->socketserver(), rtcp_socket_addr)); | |
122 if (rtp_socket_ && rtcp_socket_) { | |
123 LOG(INFO) << "Allocated Rtp socket with local port " << rtpport; | |
124 rtp_socket_->SignalReadPacket.connect( | |
125 this, &RawUdpTransportChannel::OnRtpSocketReadPacket); | |
126 rtcp_socket_->SignalReadPacket.connect( | |
127 this, &RawUdpTransportChannel::OnRtcpSocketReadPacket); | |
128 local_candidate_.set_address(rtp_socket_addr); | |
129 return true; | |
130 } | |
131 } | |
132 rtp_socket_.reset(); | |
133 rtcp_socket_.reset(); | |
134 return false; | |
135 } | |
136 | |
137 void RawUdpTransportChannel::MaybeStartGathering() { | |
138 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
139 if (gathering_state_ != kIceGatheringNew) { | |
140 LOG(INFO) << "candidates gathering already done, early return"; | |
141 return; | |
142 } | |
143 SetGatheringState(kIceGatheringGathering); | |
144 TryAllocateSockets(); | |
145 SignalCandidateGathered(this, local_candidate_); | |
146 SetGatheringState(kIceGatheringComplete); | |
147 } | |
148 | |
149 void RawUdpTransportChannel::UpdateWritableState() { | |
150 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
151 bool writable = true; | |
152 if (!rtp_socket_) { | |
153 writable = false; | |
154 LOG(INFO) << "rtp_socket_ is false"; | |
155 } | |
156 if (!remote_addr_.IsComplete()) { | |
157 writable = false; | |
158 LOG(INFO) << "remote_addr_ not complete"; | |
159 } | |
160 if (gathering_state_ != kIceGatheringComplete) { | |
161 writable = false; | |
162 LOG(INFO) << "gathering_state_ " << gathering_state_; | |
163 } | |
164 set_writable(writable); | |
165 } | |
166 | |
167 void RawUdpTransportChannel::AddRemoteCandidate(const Candidate& candidate) { | |
168 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
169 // TODO(johan) check for ipv4, other settings | |
170 remote_candidate_ = candidate; | |
171 remote_addr_ = candidate.address(); | |
172 // TODO(johan) - only set STATE_COMPLETED if *both* local and remote addr are | |
173 // set. Maybe use an rtc::Optional to indicate unset addr? | |
174 SetTransportChannelState(STATE_COMPLETED); | |
175 // TODO(johan) - set STATE_FAILED, if remote addr is invalid | |
176 UpdateWritableState(); | |
177 } | |
178 | |
179 IceGatheringState RawUdpTransportChannel::gathering_state() const { | |
180 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
181 return gathering_state_; | |
182 } | |
183 | |
184 bool RawUdpTransportChannel::SetRemoteAddrAndPorts(const char* ip_addr, | |
185 int rtp_port) { | |
186 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
187 remote_addr_ = rtc::SocketAddress(ip_addr, rtp_port); | |
188 return true; | |
189 } | |
190 | |
191 TransportChannelState RawUdpTransportChannel::GetState() const { | |
192 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
193 return tch_state_; | |
194 } | |
195 | |
196 void RawUdpTransportChannel::SetGatheringState( | |
197 IceGatheringState new_gathering_state) { | |
198 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
199 /* | |
200 kIceGatheringNew = 0, | |
201 kIceGatheringGathering, | |
202 kIceGatheringComplete, | |
203 */ | |
sprang_webrtc
2016/10/07 09:56:21
Remove this comment
johan
2016/10/07 12:24:26
Acknowledged.
| |
204 if (gathering_state_ != new_gathering_state) { | |
205 gathering_state_ = new_gathering_state; | |
206 SignalGatheringState(this); | |
207 } | |
208 } | |
209 | |
210 void RawUdpTransportChannel::SetTransportChannelState( | |
211 TransportChannelState new_tch_state) { | |
212 RTC_DCHECK_EQ(network_thread_, rtc::Thread::Current()); | |
213 /* | |
214 STATE_INIT, | |
215 STATE_CONNECTING, // Will enter this state once a connection is created | |
216 STATE_COMPLETED, | |
217 STATE_FAILED | |
218 */ | |
sprang_webrtc
2016/10/07 09:56:21
Remove this comment.
johan
2016/10/07 12:24:26
Acknowledged.
| |
219 if (tch_state_ != new_tch_state) { | |
220 tch_state_ = new_tch_state; | |
221 SignalStateChanged(this); | |
222 } | |
223 } | |
224 } // namespace cricket | |
OLD | NEW |