Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Unified Diff: media/cast/test/transport/transport.cc

Issue 56333003: Adding transport to Cast/test (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Responding to review Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/cast/test/transport/transport.h ('k') | media/cast/test/transport/transport.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/cast/test/transport/transport.cc
diff --git a/media/cast/test/transport/transport.cc b/media/cast/test/transport/transport.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b5cc2f540505618f203e50db8570b363dc8882da
--- /dev/null
+++ b/media/cast/test/transport/transport.cc
@@ -0,0 +1,176 @@
+// Copyright 2013 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/test/transport/transport.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/rand_util.h"
+#include "net/base/completion_callback.h"
+#include "net/base/io_buffer.h"
+#include "net/base/rand_callback.h"
+#include "net/base/test_completion_callback.h"
+
+namespace media {
+namespace cast {
+namespace test {
+
+const int kMaxPacketSize = 1500;
+
+class LocalUdpTransportData;
+
+void CreateUDPAddress(std::string ip_str, int port, net::IPEndPoint* address) {
+ net::IPAddressNumber ip_number;
+ bool rv = net::ParseIPLiteralToNumber(ip_str, &ip_number);
+ if (!rv)
+ return;
+ *address = net::IPEndPoint(ip_number, port);
+}
+
+class LocalUdpTransportData {
+ public:
+ LocalUdpTransportData(net::DatagramServerSocket* udp_socket)
+ : udp_socket_(udp_socket),
+ buffer_(new net::IOBufferWithSize(kMaxPacketSize)),
+ weak_factory_(this) {
+ }
+
+ void ListenTo(net::IPEndPoint bind_address) {
+ bind_address_ = bind_address;
+ RecvFromSocketLoop();
+ }
+
+ void PacketReceived(int result) {
+ // Got a packet with length result.
+ uint8* data = reinterpret_cast<uint8*>(buffer_->data());
+ packet_receiver_->ReceivedPacket(data, result,
+ base::Bind(&LocalUdpTransportData::DeletePacket,
+ weak_factory_.GetWeakPtr(), data));
+ }
+
+ void RecvFromSocketLoop() {
+ // Callback should always trigger with a packet.
+ int res = udp_socket_->RecvFrom(buffer_.get(), kMaxPacketSize,
+ &bind_address_, base::Bind(&LocalUdpTransportData::RecvFromSocketLoop,
+ weak_factory_.GetWeakPtr()));
+ DCHECK(res >= net::IO_PENDING);
+ if (res > 0) {
+ PacketReceived(res);
+ }
+ }
+
+ void set_packet_receiver(PacketReceiver* packet_receiver) {
+ packet_receiver_ = packet_receiver;
+ }
+
+ void Close() {
+ udp_socket_->Close();
+ }
+
+ private:
+ net::DatagramServerSocket* udp_socket_;
+ net::IPEndPoint bind_address_;
+ PacketReceiver* packet_receiver_;
+ scoped_refptr<net::IOBufferWithSize> buffer_;
+ base::WeakPtrFactory<LocalUdpTransportData> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(LocalUdpTransportData);
+};
+
+class LocalPacketSender : public PacketSender {
+ public:
+ explicit LocalPacketSender(net::DatagramServerSocket* udp_socket)
+ : udp_socket_(udp_socket),
+ send_address_(),
+ loss_limit_(0) {}
+
+ virtual bool SendPacket(const Packet& packet) {
+ const uint8* data = packet.data();
+ if (loss_limit_ > 0) {
+ int r = base::RandInt(0, 100);
+ if (r < loss_limit_) {
+ VLOG(1) << "Drop packet f:" << static_cast<int>(data[12 + 1])
+ << " p:" << static_cast<int>(data[12 + 3])
+ << " m:" << static_cast<int>(data[12 + 5]);
+ return true;
+ }
+ }
+ net::TestCompletionCallback callback;
+ scoped_refptr<net::WrappedIOBuffer> buffer(
+ new net::WrappedIOBuffer(reinterpret_cast<const char*>(data)));
+ int rv = udp_socket_->SendTo(
+ buffer.get(), packet.size(), send_address_, callback.callback());
+ return (rv == packet.size());
+ }
+
+ virtual bool SendPackets(const PacketList& packets) {
+ bool out_val = true;
+ for (size_t i = 0; i < packets.size(); ++i) {
+ const Packet& packet = packets[i];
+ out_val |= SendPacket(packet);
+ }
+ return out_val;
+ }
+
+ void SetPacketLoss(int percentage) {
+ DCHECK(percentage >= 0);
+ DCHECK(percentage < 100);
+ loss_limit_ = percentage;
+ }
+
+ void SetSendAddress(net::IPEndPoint& send_address) {
+ send_address_ = send_address;
+ }
+
+ private:
+ net::DatagramServerSocket* udp_socket_; // Not owned by this class.
+ net::IPEndPoint send_address_;
+ int loss_limit_;
+};
+
+Transport::Transport(scoped_refptr<CastEnvironment> cast_environment)
+ : udp_socket_(new net::UDPServerSocket(NULL, net::NetLog::Source())),
+ local_udp_transport_data_(new LocalUdpTransportData(udp_socket_.get())),
+ packet_sender_(new LocalPacketSender(udp_socket_.get())) {}
+
+Transport::~Transport() {}
+
+PacketSender* Transport::packet_sender() {
+ return static_cast<PacketSender*>(packet_sender_.get());
+}
+
+void Transport::SetSendSidePacketLoss(int percentage) {
+ packet_sender_->SetPacketLoss(percentage);
+}
+
+void Transport::StopReceiving() {
+ local_udp_transport_data_->Close();
+}
+
+void Transport::SetLocalReceiver(PacketReceiver* packet_receiver,
+ std::string ip_address,
+ int port) {
+ net::IPEndPoint bind_address;
+ CreateUDPAddress(ip_address, port, &bind_address);
+ local_udp_transport_data_->set_packet_receiver(packet_receiver);
+ udp_socket_->AllowAddressReuse();
+ udp_socket_->SetMulticastLoopbackMode(true);
+ udp_socket_->Listen(bind_address);
+
+ // Start listening once receiver has been set.
+ local_udp_transport_data_->ListenTo(bind_address);
+}
+
+void Transport::SetSendDestination(std::string ip_address, int port) {
+ net::IPEndPoint send_address;
+ CreateUDPAddress(ip_address, port, &send_address);
+ packet_sender_->SetSendAddress(send_address);
+}
+
+} // namespace test
+} // namespace cast
+} // namespace media
« no previous file with comments | « media/cast/test/transport/transport.h ('k') | media/cast/test/transport/transport.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698