OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/net/udp_transport.h" | 5 #include "media/cast/net/udp_transport.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 send_buffer_size_(send_buffer_size), | 58 send_buffer_size_(send_buffer_size), |
59 status_callback_(status_callback), | 59 status_callback_(status_callback), |
60 bytes_sent_(0), | 60 bytes_sent_(0), |
61 weak_factory_(this) { | 61 weak_factory_(this) { |
62 DCHECK(!IsEmpty(local_end_point) || !IsEmpty(remote_end_point)); | 62 DCHECK(!IsEmpty(local_end_point) || !IsEmpty(remote_end_point)); |
63 } | 63 } |
64 | 64 |
65 UdpTransport::~UdpTransport() {} | 65 UdpTransport::~UdpTransport() {} |
66 | 66 |
67 void UdpTransport::StartReceiving( | 67 void UdpTransport::StartReceiving( |
68 const PacketReceiverCallback& packet_receiver) { | 68 const PacketReceiverCallbackWithStatus& packet_receiver) { |
69 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 69 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
70 | 70 |
71 packet_receiver_ = packet_receiver; | 71 packet_receiver_ = packet_receiver; |
72 udp_socket_->AllowAddressReuse(); | 72 udp_socket_->AllowAddressReuse(); |
73 udp_socket_->SetMulticastLoopbackMode(true); | 73 udp_socket_->SetMulticastLoopbackMode(true); |
74 if (!IsEmpty(local_addr_)) { | 74 if (!IsEmpty(local_addr_)) { |
75 if (udp_socket_->Bind(local_addr_) < 0) { | 75 if (udp_socket_->Bind(local_addr_) < 0) { |
76 status_callback_.Run(TRANSPORT_SOCKET_ERROR); | 76 status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
77 LOG(ERROR) << "Failed to bind local address."; | 77 LOG(ERROR) << "Failed to bind local address."; |
78 return; | 78 return; |
79 } | 79 } |
80 } else if (!IsEmpty(remote_addr_)) { | 80 } else if (!IsEmpty(remote_addr_)) { |
81 if (udp_socket_->Connect(remote_addr_) < 0) { | 81 if (udp_socket_->Connect(remote_addr_) < 0) { |
82 status_callback_.Run(TRANSPORT_SOCKET_ERROR); | 82 status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
83 LOG(ERROR) << "Failed to connect to remote address."; | 83 LOG(ERROR) << "Failed to connect to remote address."; |
84 return; | 84 return; |
85 } | 85 } |
86 client_connected_ = true; | 86 client_connected_ = true; |
87 } else { | 87 } else { |
88 NOTREACHED() << "Either local or remote address has to be defined."; | 88 NOTREACHED() << "Either local or remote address has to be defined."; |
89 } | 89 } |
90 if (udp_socket_->SetSendBufferSize(send_buffer_size_) != net::OK) { | 90 if (udp_socket_->SetSendBufferSize(send_buffer_size_) != net::OK) { |
91 LOG(WARNING) << "Failed to set socket send buffer size."; | 91 LOG(WARNING) << "Failed to set socket send buffer size."; |
92 } | 92 } |
93 | 93 |
94 ScheduleReceiveNextPacket(); | 94 ScheduleReceiveNextPacket(); |
95 } | 95 } |
96 | 96 |
97 void UdpTransport::StopReceiving() { | |
98 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | |
99 packet_receiver_ = PacketReceiverCallbackWithStatus(); | |
100 } | |
101 | |
102 | |
97 void UdpTransport::SetDscp(net::DiffServCodePoint dscp) { | 103 void UdpTransport::SetDscp(net::DiffServCodePoint dscp) { |
98 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 104 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
99 next_dscp_value_ = dscp; | 105 next_dscp_value_ = dscp; |
100 } | 106 } |
101 | 107 |
102 void UdpTransport::ScheduleReceiveNextPacket() { | 108 void UdpTransport::ScheduleReceiveNextPacket() { |
103 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 109 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
104 if (!packet_receiver_.is_null() && !receive_pending_) { | 110 if (!packet_receiver_.is_null() && !receive_pending_) { |
105 receive_pending_ = true; | 111 receive_pending_ = true; |
106 io_thread_proxy_->PostTask(FROM_HERE, | 112 io_thread_proxy_->PostTask(FROM_HERE, |
107 base::Bind(&UdpTransport::ReceiveNextPacket, | 113 base::Bind(&UdpTransport::ReceiveNextPacket, |
108 weak_factory_.GetWeakPtr(), | 114 weak_factory_.GetWeakPtr(), |
109 net::ERR_IO_PENDING)); | 115 net::ERR_IO_PENDING)); |
110 } | 116 } |
111 } | 117 } |
112 | 118 |
113 void UdpTransport::ReceiveNextPacket(int length_or_status) { | 119 void UdpTransport::ReceiveNextPacket(int length_or_status) { |
114 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 120 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
115 | 121 |
116 // Loop while UdpSocket is delivering data synchronously. When it responds | 122 // Loop while UdpSocket is delivering data synchronously. When it responds |
miu
2014/12/04 04:18:54
Looks like ReceiveNextPacket() could be called fro
hubbe
2014/12/05 23:57:20
Done.
| |
117 // with a "pending" status, break and expect this method to be called back in | 123 // with a "pending" status, break and expect this method to be called back in |
118 // the future when a packet is ready. | 124 // the future when a packet is ready. |
119 while (true) { | 125 while (true) { |
120 if (length_or_status == net::ERR_IO_PENDING) { | 126 if (length_or_status == net::ERR_IO_PENDING) { |
121 next_packet_.reset(new Packet(kMaxPacketSize)); | 127 next_packet_.reset(new Packet(kMaxPacketSize)); |
122 recv_buf_ = new net::WrappedIOBuffer( | 128 recv_buf_ = new net::WrappedIOBuffer( |
123 reinterpret_cast<char*>(&next_packet_->front())); | 129 reinterpret_cast<char*>(&next_packet_->front())); |
124 length_or_status = | 130 length_or_status = |
125 udp_socket_->RecvFrom(recv_buf_.get(), | 131 udp_socket_->RecvFrom(recv_buf_.get(), |
126 kMaxPacketSize, | 132 kMaxPacketSize, |
(...skipping 16 matching lines...) Expand all Loading... | |
143 | 149 |
144 // Confirm the packet has come from the expected remote address; otherwise, | 150 // Confirm the packet has come from the expected remote address; otherwise, |
145 // ignore it. If this is the first packet being received and no remote | 151 // ignore it. If this is the first packet being received and no remote |
146 // address has been set, set the remote address and expect all future | 152 // address has been set, set the remote address and expect all future |
147 // packets to come from the same one. | 153 // packets to come from the same one. |
148 // TODO(hubbe): We should only do this if the caller used a valid ssrc. | 154 // TODO(hubbe): We should only do this if the caller used a valid ssrc. |
149 if (IsEmpty(remote_addr_)) { | 155 if (IsEmpty(remote_addr_)) { |
150 remote_addr_ = recv_addr_; | 156 remote_addr_ = recv_addr_; |
151 VLOG(1) << "Setting remote address from first received packet: " | 157 VLOG(1) << "Setting remote address from first received packet: " |
152 << remote_addr_.ToString(); | 158 << remote_addr_.ToString(); |
159 next_packet_->resize(length_or_status); | |
160 if (!packet_receiver_.Run(next_packet_.Pass())) { | |
161 VLOG(1) << "Packet was not valid, resetting remote address."; | |
162 remote_addr_ = net::IPEndPoint(); | |
163 } | |
164 length_or_status = net::ERR_IO_PENDING; | |
153 } else if (!IsEqual(remote_addr_, recv_addr_)) { | 165 } else if (!IsEqual(remote_addr_, recv_addr_)) { |
154 VLOG(1) << "Ignoring packet received from an unrecognized address: " | 166 VLOG(1) << "Ignoring packet received from an unrecognized address: " |
155 << recv_addr_.ToString() << "."; | 167 << recv_addr_.ToString() << "."; |
156 length_or_status = net::ERR_IO_PENDING; | 168 length_or_status = net::ERR_IO_PENDING; |
157 continue; | 169 continue; |
miu
2014/12/04 04:18:55
Don't need the continue-statement anymore.
hubbe
2014/12/05 23:57:20
Done.
| |
170 } else { | |
171 next_packet_->resize(length_or_status); | |
172 packet_receiver_.Run(next_packet_.Pass()); | |
173 length_or_status = net::ERR_IO_PENDING; | |
miu
2014/12/04 04:18:55
Since length_or_status is assigned the same from a
hubbe
2014/12/05 23:57:20
Done.
| |
158 } | 174 } |
159 | |
160 next_packet_->resize(length_or_status); | |
161 packet_receiver_.Run(next_packet_.Pass()); | |
162 length_or_status = net::ERR_IO_PENDING; | |
163 } | 175 } |
164 } | 176 } |
165 | 177 |
166 bool UdpTransport::SendPacket(PacketRef packet, const base::Closure& cb) { | 178 bool UdpTransport::SendPacket(PacketRef packet, const base::Closure& cb) { |
167 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); | 179 DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
168 | 180 |
169 // Increase byte count no matter the packet was sent or dropped. | 181 // Increase byte count no matter the packet was sent or dropped. |
170 bytes_sent_ += packet->data.size(); | 182 bytes_sent_ += packet->data.size(); |
171 | 183 |
172 DCHECK(!send_pending_); | 184 DCHECK(!send_pending_); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 } | 250 } |
239 ScheduleReceiveNextPacket(); | 251 ScheduleReceiveNextPacket(); |
240 | 252 |
241 if (!cb.is_null()) { | 253 if (!cb.is_null()) { |
242 cb.Run(); | 254 cb.Run(); |
243 } | 255 } |
244 } | 256 } |
245 | 257 |
246 } // namespace cast | 258 } // namespace cast |
247 } // namespace media | 259 } // namespace media |
OLD | NEW |