Index: media/cast/transport/transport/udp_transport.cc |
diff --git a/media/cast/transport/transport/udp_transport.cc b/media/cast/transport/transport/udp_transport.cc |
deleted file mode 100644 |
index 9669b17d4386a24fed929adeb96804cfaf996f5a..0000000000000000000000000000000000000000 |
--- a/media/cast/transport/transport/udp_transport.cc |
+++ /dev/null |
@@ -1,242 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "media/cast/transport/transport/udp_transport.h" |
- |
-#include <algorithm> |
-#include <string> |
- |
-#include "base/bind.h" |
-#include "base/logging.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/rand_util.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/rand_callback.h" |
- |
-namespace media { |
-namespace cast { |
-namespace transport { |
- |
-namespace { |
-const int kMaxPacketSize = 1500; |
- |
-bool IsEmpty(const net::IPEndPoint& addr) { |
- net::IPAddressNumber empty_addr(addr.address().size()); |
- return std::equal( |
- empty_addr.begin(), empty_addr.end(), addr.address().begin()) && |
- !addr.port(); |
-} |
- |
-bool IsEqual(const net::IPEndPoint& addr1, const net::IPEndPoint& addr2) { |
- return addr1.port() == addr2.port() && std::equal(addr1.address().begin(), |
- addr1.address().end(), |
- addr2.address().begin()); |
-} |
-} // namespace |
- |
-UdpTransport::UdpTransport( |
- net::NetLog* net_log, |
- const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_proxy, |
- const net::IPEndPoint& local_end_point, |
- const net::IPEndPoint& remote_end_point, |
- const CastTransportStatusCallback& status_callback) |
- : io_thread_proxy_(io_thread_proxy), |
- local_addr_(local_end_point), |
- remote_addr_(remote_end_point), |
- udp_socket_(new net::UDPSocket(net::DatagramSocket::DEFAULT_BIND, |
- net::RandIntCallback(), |
- net_log, |
- net::NetLog::Source())), |
- send_pending_(false), |
- receive_pending_(false), |
- client_connected_(false), |
- next_dscp_value_(net::DSCP_NO_CHANGE), |
- status_callback_(status_callback), |
- weak_factory_(this) { |
- DCHECK(!IsEmpty(local_end_point) || !IsEmpty(remote_end_point)); |
-} |
- |
-UdpTransport::~UdpTransport() {} |
- |
-void UdpTransport::StartReceiving( |
- const PacketReceiverCallback& packet_receiver) { |
- DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
- |
- packet_receiver_ = packet_receiver; |
- udp_socket_->AllowAddressReuse(); |
- udp_socket_->SetMulticastLoopbackMode(true); |
- if (!IsEmpty(local_addr_)) { |
- if (udp_socket_->Bind(local_addr_) < 0) { |
- status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
- LOG(ERROR) << "Failed to bind local address."; |
- return; |
- } |
- } else if (!IsEmpty(remote_addr_)) { |
- if (udp_socket_->Connect(remote_addr_) < 0) { |
- status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
- LOG(ERROR) << "Failed to connect to remote address."; |
- return; |
- } |
- client_connected_ = true; |
- } else { |
- NOTREACHED() << "Either local or remote address has to be defined."; |
- } |
- |
- ScheduleReceiveNextPacket(); |
-} |
- |
-void UdpTransport::SetDscp(net::DiffServCodePoint dscp) { |
- DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
- next_dscp_value_ = dscp; |
-} |
- |
-void UdpTransport::ScheduleReceiveNextPacket() { |
- DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
- if (!packet_receiver_.is_null() && !receive_pending_) { |
- receive_pending_ = true; |
- io_thread_proxy_->PostTask(FROM_HERE, |
- base::Bind(&UdpTransport::ReceiveNextPacket, |
- weak_factory_.GetWeakPtr(), |
- net::ERR_IO_PENDING)); |
- } |
-} |
- |
-void UdpTransport::ReceiveNextPacket(int length_or_status) { |
- DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
- |
- // Loop while UdpSocket is delivering data synchronously. When it responds |
- // with a "pending" status, break and expect this method to be called back in |
- // the future when a packet is ready. |
- while (true) { |
- if (length_or_status == net::ERR_IO_PENDING) { |
- next_packet_.reset(new Packet(kMaxPacketSize)); |
- recv_buf_ = new net::WrappedIOBuffer( |
- reinterpret_cast<char*>(&next_packet_->front())); |
- length_or_status = udp_socket_->RecvFrom( |
- recv_buf_, |
- kMaxPacketSize, |
- &recv_addr_, |
- base::Bind(&UdpTransport::ReceiveNextPacket, |
- weak_factory_.GetWeakPtr())); |
- if (length_or_status == net::ERR_IO_PENDING) { |
- receive_pending_ = true; |
- return; |
- } |
- } |
- |
- // Note: At this point, either a packet is ready or an error has occurred. |
- if (length_or_status < 0) { |
- VLOG(1) << "Failed to receive packet: Status code is " |
- << length_or_status; |
- status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
- receive_pending_ = false; |
- return; |
- } |
- |
- // Confirm the packet has come from the expected remote address; otherwise, |
- // ignore it. If this is the first packet being received and no remote |
- // address has been set, set the remote address and expect all future |
- // packets to come from the same one. |
- // TODO(hubbe): We should only do this if the caller used a valid ssrc. |
- if (IsEmpty(remote_addr_)) { |
- remote_addr_ = recv_addr_; |
- VLOG(1) << "Setting remote address from first received packet: " |
- << remote_addr_.ToString(); |
- } else if (!IsEqual(remote_addr_, recv_addr_)) { |
- VLOG(1) << "Ignoring packet received from an unrecognized address: " |
- << recv_addr_.ToString() << "."; |
- length_or_status = net::ERR_IO_PENDING; |
- continue; |
- } |
- |
- next_packet_->resize(length_or_status); |
- packet_receiver_.Run(next_packet_.Pass()); |
- length_or_status = net::ERR_IO_PENDING; |
- } |
-} |
- |
-bool UdpTransport::SendPacket(PacketRef packet, const base::Closure& cb) { |
- DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
- |
- DCHECK(!send_pending_); |
- if (send_pending_) { |
- VLOG(1) << "Cannot send because of pending IO."; |
- return true; |
- } |
- |
- if (next_dscp_value_ != net::DSCP_NO_CHANGE) { |
- int result = udp_socket_->SetDiffServCodePoint(next_dscp_value_); |
- if (result != net::OK) { |
- LOG(ERROR) << "Unable to set DSCP: " << next_dscp_value_ |
- << " to socket; Error: " << result; |
- } |
- // Don't change DSCP in next send. |
- next_dscp_value_ = net::DSCP_NO_CHANGE; |
- } |
- |
- scoped_refptr<net::IOBuffer> buf = |
- new net::WrappedIOBuffer(reinterpret_cast<char*>(&packet->data.front())); |
- |
- int result; |
- base::Callback<void(int)> callback = base::Bind(&UdpTransport::OnSent, |
- weak_factory_.GetWeakPtr(), |
- buf, |
- packet, |
- cb); |
- if (client_connected_) { |
- // If we called Connect() before we must call Write() instead of |
- // SendTo(). Otherwise on some platforms we might get |
- // ERR_SOCKET_IS_CONNECTED. |
- result = udp_socket_->Write(buf, |
- static_cast<int>(packet->data.size()), |
- callback); |
- } else if (!IsEmpty(remote_addr_)) { |
- result = udp_socket_->SendTo(buf, |
- static_cast<int>(packet->data.size()), |
- remote_addr_, |
- callback); |
- } else { |
- return true; |
- } |
- |
- if (result == net::ERR_IO_PENDING) { |
- send_pending_ = true; |
- return false; |
- } else if (result < 0) { |
- LOG(ERROR) << "Failed to send packet: " << result << "."; |
- status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
- return true; |
- } else { |
- // Successful send, re-start reading if needed. |
- ScheduleReceiveNextPacket(); |
- return true; |
- } |
-} |
- |
-void UdpTransport::OnSent(const scoped_refptr<net::IOBuffer>& buf, |
- PacketRef packet, |
- const base::Closure& cb, |
- int result) { |
- DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread()); |
- |
- send_pending_ = false; |
- if (result < 0) { |
- LOG(ERROR) << "Failed to send packet: " << result << "."; |
- status_callback_.Run(TRANSPORT_SOCKET_ERROR); |
- } else { |
- // Successful send, re-start reading if needed. |
- ScheduleReceiveNextPacket(); |
- } |
- |
- if (!cb.is_null()) { |
- cb.Run(); |
- } |
-} |
- |
-} // namespace transport |
-} // namespace cast |
-} // namespace media |