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