1// Copyright 2010 Google Inc. All Rights Reserved,
2//
3// Author: Justin Uberti (juberti@google.com)
4
5#ifndef TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_
6#define TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_
7
8#include <string>
9#include "talk/base/scoped_ptr.h"
10#include "talk/p2p/base/basicpacketsocketfactory.h"
11#include "talk/p2p/base/portallocator.h"
12#include "talk/p2p/base/udpport.h"
13
14namespace talk_base {
15class SocketFactory;
16class Thread;
17}
18
19namespace cricket {
20
21class FakePortAllocatorSession : public PortAllocatorSession {
22 public:
23  FakePortAllocatorSession(talk_base::Thread* worker_thread,
24                           talk_base::PacketSocketFactory* factory,
25                           const std::string& content_name,
26                           int component,
27                           const std::string& ice_ufrag,
28                           const std::string& ice_pwd)
29      : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd,
30                             cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG),
31        worker_thread_(worker_thread),
32        factory_(factory),
33        network_("network", "unittest",
34                 talk_base::IPAddress(INADDR_LOOPBACK), 8),
35        port_(), running_(false),
36        port_config_count_(0) {
37    network_.AddIP(talk_base::IPAddress(INADDR_LOOPBACK));
38  }
39
40  virtual void StartGettingPorts() {
41    if (!port_) {
42      port_.reset(cricket::UDPPort::Create(worker_thread_, factory_,
43                      &network_, network_.ip(), 0, 0,
44                      username(),
45                      password()));
46      AddPort(port_.get());
47    }
48    ++port_config_count_;
49    running_ = true;
50  }
51
52  virtual void StopGettingPorts() { running_ = false; }
53  virtual bool IsGettingPorts() { return running_; }
54  int port_config_count() { return port_config_count_; }
55
56  void AddPort(cricket::Port* port) {
57    port->set_component(component_);
58    port->set_generation(0);
59    port->SignalPortComplete.connect(
60        this, &FakePortAllocatorSession::OnPortComplete);
61    port->PrepareAddress();
62    SignalPortReady(this, port);
63  }
64  void OnPortComplete(cricket::Port* port) {
65    SignalCandidatesReady(this, port->Candidates());
66    SignalCandidatesAllocationDone(this);
67  }
68
69 private:
70  talk_base::Thread* worker_thread_;
71  talk_base::PacketSocketFactory* factory_;
72  talk_base::Network network_;
73  talk_base::scoped_ptr<cricket::Port> port_;
74  bool running_;
75  int port_config_count_;
76};
77
78class FakePortAllocator : public cricket::PortAllocator {
79 public:
80  FakePortAllocator(talk_base::Thread* worker_thread,
81                    talk_base::PacketSocketFactory* factory)
82      : worker_thread_(worker_thread), factory_(factory) {
83    if (factory_ == NULL) {
84      owned_factory_.reset(new talk_base::BasicPacketSocketFactory(
85          worker_thread_));
86      factory_ = owned_factory_.get();
87    }
88  }
89
90  virtual cricket::PortAllocatorSession* CreateSessionInternal(
91      const std::string& content_name,
92      int component,
93      const std::string& ice_ufrag,
94      const std::string& ice_pwd) {
95    return new FakePortAllocatorSession(
96        worker_thread_, factory_, content_name, component, ice_ufrag, ice_pwd);
97  }
98
99 private:
100  talk_base::Thread* worker_thread_;
101  talk_base::PacketSocketFactory* factory_;
102  talk_base::scoped_ptr<talk_base::BasicPacketSocketFactory> owned_factory_;
103};
104
105}  // namespace cricket
106
107#endif  // TALK_P2P_CLIENT_FAKEPORTALLOCATOR_H_
108