15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef MEDIA_CAST_NET_UDP_TRANSPORT_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define MEDIA_CAST_NET_UDP_TRANSPORT_H_
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/ref_counted.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/weak_ptr.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cast/cast_environment.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/cast_transport_config.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/cast_transport_sender.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/ip_endpoint.h"
156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "net/base/net_util.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/udp/udp_socket.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class IOBuffer;
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class IPEndPoint;
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class NetLog;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace cast {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This class implements UDP transport mechanism for Cast.
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class UdpTransport : public PacketSender {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Construct a UDP transport.
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // All methods must be called on |io_thread_proxy|.
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |local_end_point| specifies the address and port to bind and listen
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to incoming packets. If the value is 0.0.0.0:0 then a bind is not
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // performed.
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |remote_end_point| specifies the address and port to send packets
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to. If the value is 0.0.0.0:0 the the end point is set to the source
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // address of the first packet received.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UdpTransport(
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::NetLog* net_log,
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_proxy,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::IPEndPoint& local_end_point,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::IPEndPoint& remote_end_point,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const CastTransportStatusCallback& status_callback);
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~UdpTransport();
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Start receiving packets. Packets are submitted to |packet_receiver|.
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void StartReceiving(const PacketReceiverCallback& packet_receiver);
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Set a new DSCP value to the socket. The value will be set right before
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // the next send.
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void SetDscp(net::DiffServCodePoint dscp);
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // PacketSender implementations.
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual bool SendPacket(PacketRef packet,
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          const base::Closure& cb) OVERRIDE;
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual int64 GetBytesSent() OVERRIDE;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests and processes packets from |udp_socket_|.  This method is called
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // once with |length_or_status| set to net::ERR_IO_PENDING to start receiving
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // packets.  Thereafter, it is called with some other value as the callback
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // response from UdpSocket::RecvFrom().
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ReceiveNextPacket(int length_or_status);
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Schedule packet receiving, if needed.
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void ScheduleReceiveNextPacket();
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void OnSent(const scoped_refptr<net::IOBuffer>& buf,
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              PacketRef packet,
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              const base::Closure& cb,
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              int result);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const scoped_refptr<base::SingleThreadTaskRunner> io_thread_proxy_;
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const net::IPEndPoint local_addr_;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::IPEndPoint remote_addr_;
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const scoped_ptr<net::UDPSocket> udp_socket_;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool send_pending_;
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool receive_pending_;
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool client_connected_;
806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  net::DiffServCodePoint next_dscp_value_;
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<Packet> next_packet_;
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<net::WrappedIOBuffer> recv_buf_;
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::IPEndPoint recv_addr_;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PacketReceiverCallback packet_receiver_;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const CastTransportStatusCallback status_callback_;
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int bytes_sent_;
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: Weak pointers must be invalidated before all other member variables.
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::WeakPtrFactory<UdpTransport> weak_factory_;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UdpTransport);
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace cast
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // MEDIA_CAST_NET_UDP_TRANSPORT_H_
98