Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / jingle / glue / fake_socket_factory.cc
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "jingle/glue/fake_socket_factory.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "jingle/glue/utils.h"
10 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
11 #include "third_party/libjingle/source/talk/base/asyncsocket.h"
12
13 namespace jingle_glue {
14
15 FakeUDPPacketSocket::FakeUDPPacketSocket(FakeSocketManager* fake_socket_manager,
16                                          const net::IPEndPoint& address)
17     : fake_socket_manager_(fake_socket_manager),
18       endpoint_(address), state_(IS_OPEN), error_(0) {
19   CHECK(IPEndPointToSocketAddress(endpoint_, &local_address_));
20   fake_socket_manager_->AddSocket(this);
21 }
22
23 FakeUDPPacketSocket::~FakeUDPPacketSocket() {
24   fake_socket_manager_->RemoveSocket(this);
25 }
26
27 talk_base::SocketAddress FakeUDPPacketSocket::GetLocalAddress() const {
28   DCHECK(CalledOnValidThread());
29   return local_address_;
30 }
31
32 talk_base::SocketAddress FakeUDPPacketSocket::GetRemoteAddress() const {
33   DCHECK(CalledOnValidThread());
34   return remote_address_;
35 }
36
37 int FakeUDPPacketSocket::Send(const void *data, size_t data_size,
38                               talk_base::DiffServCodePoint dscp) {
39   DCHECK(CalledOnValidThread());
40   return SendTo(data, data_size, remote_address_, dscp);
41 }
42
43 int FakeUDPPacketSocket::SendTo(const void *data, size_t data_size,
44                                 const talk_base::SocketAddress& address,
45                                 talk_base::DiffServCodePoint dscp) {
46   DCHECK(CalledOnValidThread());
47
48   if (state_ == IS_CLOSED) {
49     return ENOTCONN;
50   }
51
52   net::IPEndPoint destination;
53   if (!SocketAddressToIPEndPoint(address, &destination)) {
54     return EINVAL;
55   }
56
57   const char* data_char = reinterpret_cast<const char*>(data);
58   std::vector<char> data_vector(data_char, data_char + data_size);
59
60   fake_socket_manager_->SendPacket(endpoint_, destination, data_vector);
61
62   return data_size;
63 }
64
65 int FakeUDPPacketSocket::Close() {
66   DCHECK(CalledOnValidThread());
67   state_ = IS_CLOSED;
68   return 0;
69 }
70
71 talk_base::AsyncPacketSocket::State FakeUDPPacketSocket::GetState() const {
72   DCHECK(CalledOnValidThread());
73
74   switch (state_) {
75     case IS_OPEN:
76       return STATE_BOUND;
77     case IS_CLOSED:
78       return STATE_CLOSED;
79   }
80
81   NOTREACHED();
82   return STATE_CLOSED;
83 }
84
85 int FakeUDPPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) {
86   DCHECK(CalledOnValidThread());
87   return -1;
88 }
89
90 int FakeUDPPacketSocket::SetOption(talk_base::Socket::Option opt, int value) {
91   DCHECK(CalledOnValidThread());
92   return -1;
93 }
94
95 int FakeUDPPacketSocket::GetError() const {
96   DCHECK(CalledOnValidThread());
97   return error_;
98 }
99
100 void FakeUDPPacketSocket::SetError(int error) {
101   DCHECK(CalledOnValidThread());
102   error_ = error;
103 }
104
105 void FakeUDPPacketSocket::DeliverPacket(const net::IPEndPoint& from,
106                                         const std::vector<char>& data) {
107   DCHECK(CalledOnValidThread());
108
109   talk_base::SocketAddress address;
110   if (!jingle_glue::IPEndPointToSocketAddress(from, &address)) {
111     // We should always be able to convert address here because we
112     // don't expect IPv6 address on IPv4 connections.
113     NOTREACHED();
114     return;
115   }
116
117   SignalReadPacket(this, &data[0], data.size(), address,
118                    talk_base::CreatePacketTime(0));
119 }
120
121 FakeSocketManager::FakeSocketManager()
122     : message_loop_(base::MessageLoop::current()) {}
123
124 FakeSocketManager::~FakeSocketManager() { }
125
126 void FakeSocketManager::SendPacket(const net::IPEndPoint& from,
127                                    const net::IPEndPoint& to,
128                                    const std::vector<char>& data) {
129   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
130
131   message_loop_->PostTask(
132       FROM_HERE,
133       base::Bind(&FakeSocketManager::DeliverPacket, this, from, to, data));
134 }
135
136 void FakeSocketManager::DeliverPacket(const net::IPEndPoint& from,
137                                       const net::IPEndPoint& to,
138                                       const std::vector<char>& data) {
139   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
140
141   std::map<net::IPEndPoint, FakeUDPPacketSocket*>::iterator it =
142       endpoints_.find(to);
143   if (it == endpoints_.end()) {
144     LOG(WARNING) << "Dropping packet with unknown destination: "
145                  << to.ToString();
146     return;
147   }
148   it->second->DeliverPacket(from, data);
149 }
150
151 void FakeSocketManager::AddSocket(FakeUDPPacketSocket* socket_factory) {
152   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
153
154   endpoints_[socket_factory->endpoint()] = socket_factory;
155 }
156
157 void FakeSocketManager::RemoveSocket(FakeUDPPacketSocket* socket_factory) {
158   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
159
160   endpoints_.erase(socket_factory->endpoint());
161 }
162
163 FakeSocketFactory::FakeSocketFactory(FakeSocketManager* socket_manager,
164                                      const net::IPAddressNumber& address)
165     : socket_manager_(socket_manager),
166       address_(address),
167       last_allocated_port_(0) {
168 }
169
170 FakeSocketFactory::~FakeSocketFactory() {
171 }
172
173 talk_base::AsyncPacketSocket* FakeSocketFactory::CreateUdpSocket(
174     const talk_base::SocketAddress& local_address, int min_port, int max_port) {
175   CHECK_EQ(min_port, 0);
176   CHECK_EQ(max_port, 0);
177   return new FakeUDPPacketSocket(
178       socket_manager_.get(), net::IPEndPoint(address_, ++last_allocated_port_));
179 }
180
181 talk_base::AsyncPacketSocket* FakeSocketFactory::CreateServerTcpSocket(
182     const talk_base::SocketAddress& local_address, int min_port, int max_port,
183     int opts) {
184   // TODO(sergeyu): Implement fake TCP sockets.
185   NOTIMPLEMENTED();
186   return NULL;
187 }
188
189 talk_base::AsyncPacketSocket* FakeSocketFactory::CreateClientTcpSocket(
190     const talk_base::SocketAddress& local_address,
191     const talk_base::SocketAddress& remote_address,
192     const talk_base::ProxyInfo& proxy_info, const std::string& user_agent,
193     int opts) {
194   // TODO(sergeyu): Implement fake TCP sockets.
195   NOTIMPLEMENTED();
196   return NULL;
197 }
198
199 }  // namespace jingle_glue