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

Side by Side Diff: chrome/browser/extensions/api/socket/socket_api.cc

Issue 10134008: Add bind(), recvFrom(), sendTo() for UDP socket. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Reenable api tests Created 8 years, 8 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/socket/socket_api.h" 5 #include "chrome/browser/extensions/api/socket/socket_api.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chrome/browser/extensions/api/api_resource_controller.h" 8 #include "chrome/browser/extensions/api/api_resource_controller.h"
9 #include "chrome/browser/extensions/api/socket/socket.h" 9 #include "chrome/browser/extensions/api/socket/socket.h"
10 #include "chrome/browser/extensions/api/socket/tcp_socket.h" 10 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
11 #include "chrome/browser/extensions/api/socket/udp_socket.h" 11 #include "chrome/browser/extensions/api/socket/udp_socket.h"
12 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/extension_service.h"
13 #include "net/base/io_buffer.h" 13 #include "net/base/io_buffer.h"
14 #include "net/base/ip_endpoint.h"
14 15
15 namespace extensions { 16 namespace extensions {
16 17
18 const char kAddressKey[] = "address";
19 const char kPortKey[] = "port";
17 const char kBytesWrittenKey[] = "bytesWritten"; 20 const char kBytesWrittenKey[] = "bytesWritten";
18 const char kDataKey[] = "data"; 21 const char kDataKey[] = "data";
19 const char kSocketIdKey[] = "socketId"; 22 const char kSocketIdKey[] = "socketId";
20 const char kTCPOption[] = "tcp"; 23 const char kTCPOption[] = "tcp";
21 const char kUDPOption[] = "udp"; 24 const char kUDPOption[] = "udp";
22 25
23 const char kSocketNotFoundError[] = "Socket not found"; 26 const char kSocketNotFoundError[] = "Socket not found";
24 27
25 SocketCreateFunction::SocketCreateFunction() 28 SocketCreateFunction::SocketCreateFunction()
26 : src_id_(-1), event_notifier_(NULL) { 29 : src_id_(-1), event_notifier_(NULL) {
27 } 30 }
28 31
29 bool SocketCreateFunction::Prepare() { 32 bool SocketCreateFunction::Prepare() {
33 size_t argument_position = 0;
30 std::string socket_type_string; 34 std::string socket_type_string;
31 size_t argument_position = 0;
32 EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++, 35 EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++,
33 &socket_type_string)); 36 &socket_type_string));
34 EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++,
35 &address_));
36 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(argument_position++,
37 &port_));
38
39 if (socket_type_string == kTCPOption) 37 if (socket_type_string == kTCPOption)
40 socket_type_ = kSocketTypeTCP; 38 socket_type_ = kSocketTypeTCP;
41 else if (socket_type_string == kUDPOption) 39 else if (socket_type_string == kUDPOption)
42 socket_type_ = kSocketTypeUDP; 40 socket_type_ = kSocketTypeUDP;
43 else 41 else
44 return false; 42 return false;
45 43
46 src_id_ = ExtractSrcId(argument_position); 44 src_id_ = ExtractSrcId(1);
47 event_notifier_ = CreateEventNotifier(src_id_); 45 event_notifier_ = CreateEventNotifier(src_id_);
48 46
49 return true; 47 return true;
50 } 48 }
51 49
52 void SocketCreateFunction::Work() { 50 void SocketCreateFunction::Work() {
53 Socket* socket = NULL; 51 Socket* socket = NULL;
54 if (socket_type_ == kSocketTypeTCP) { 52 if (socket_type_ == kSocketTypeTCP) {
55 socket = new TCPSocket(address_, port_, event_notifier_); 53 socket = new TCPSocket(event_notifier_);
56 } else { 54 } else {
57 socket = new UDPSocket(address_, port_, event_notifier_); 55 socket = new UDPSocket(event_notifier_);
58 } 56 }
59 DCHECK(socket); 57 DCHECK(socket);
60 DCHECK(socket->IsValid()); 58 DCHECK(socket->IsValid());
61 59
62 DictionaryValue* result = new DictionaryValue(); 60 DictionaryValue* result = new DictionaryValue();
63 61
64 result->SetInteger(kSocketIdKey, controller()->AddAPIResource(socket)); 62 result->SetInteger(kSocketIdKey, controller()->AddAPIResource(socket));
65 result_.reset(result); 63 result_.reset(result);
66 } 64 }
67 65
68 bool SocketCreateFunction::Respond() { 66 bool SocketCreateFunction::Respond() {
69 return true; 67 return true;
70 } 68 }
71 69
72 bool SocketDestroyFunction::Prepare() { 70 bool SocketDestroyFunction::Prepare() {
73 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 71 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
74 return true; 72 return true;
75 } 73 }
76 74
77 void SocketDestroyFunction::Work() { 75 void SocketDestroyFunction::Work() {
78 controller()->RemoveAPIResource(socket_id_); 76 controller()->RemoveAPIResource(socket_id_);
79 } 77 }
80 78
81 bool SocketDestroyFunction::Respond() { 79 bool SocketDestroyFunction::Respond() {
82 return true; 80 return true;
83 } 81 }
84 82
85 bool SocketConnectFunction::Prepare() { 83 bool SocketConnectFunction::Prepare() {
86 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 84 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
85 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
86 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
87 return true; 87 return true;
88 } 88 }
89 89
90 void SocketConnectFunction::Work() { 90 void SocketConnectFunction::Work() {
91 int result = -1; 91 int result = -1;
92 Socket* socket = controller()->GetSocket(socket_id_); 92 Socket* socket = controller()->GetSocket(socket_id_);
93 if (socket) 93 if (socket)
94 result = socket->Connect(); 94 result = socket->Connect(address_, port_);
95 else 95 else
96 error_ = kSocketNotFoundError; 96 error_ = kSocketNotFoundError;
97 result_.reset(Value::CreateIntegerValue(result)); 97 result_.reset(Value::CreateIntegerValue(result));
98 } 98 }
99 99
100 bool SocketConnectFunction::Respond() { 100 bool SocketConnectFunction::Respond() {
101 return true; 101 return true;
102 } 102 }
103 103
104 bool SocketDisconnectFunction::Prepare() { 104 bool SocketDisconnectFunction::Prepare() {
105 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 105 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
106 return true; 106 return true;
107 } 107 }
108 108
109 void SocketDisconnectFunction::Work() { 109 void SocketDisconnectFunction::Work() {
110 Socket* socket = controller()->GetSocket(socket_id_); 110 Socket* socket = controller()->GetSocket(socket_id_);
111 if (socket) 111 if (socket)
112 socket->Disconnect(); 112 socket->Disconnect();
113 else 113 else
114 error_ = kSocketNotFoundError; 114 error_ = kSocketNotFoundError;
115 result_.reset(Value::CreateNullValue()); 115 result_.reset(Value::CreateNullValue());
116 } 116 }
117 117
118 bool SocketDisconnectFunction::Respond() { 118 bool SocketDisconnectFunction::Respond() {
119 return true; 119 return true;
120 } 120 }
121 121
122
123 bool SocketBindFunction::Prepare() {
124 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
125 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
126 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
127 return true;
128 }
129
130 void SocketBindFunction::Work() {
131 int result = -1;
132 Socket* socket = controller()->GetSocket(socket_id_);
133 if (socket)
134 result = socket->Bind(address_, port_);
135 else
136 error_ = kSocketNotFoundError;
137
138 result_.reset(Value::CreateIntegerValue(result));
139 }
140
141 bool SocketBindFunction::Respond() {
142 return true;
143 }
144
122 bool SocketReadFunction::Prepare() { 145 bool SocketReadFunction::Prepare() {
123 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 146 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
124 return true; 147 return true;
125 } 148 }
126 149
127 void SocketReadFunction::Work() { 150 void SocketReadFunction::Work() {
128 // TODO(miket): this is an arbitrary number. Can we come up with one that 151 // TODO(miket): this is an arbitrary number. Can we come up with one that
129 // makes sense? 152 // makes sense?
130 const int buffer_len = 2048; 153 const int buffer_len = 2048;
131 scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len)); 154 scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 218
196 DictionaryValue* result = new DictionaryValue(); 219 DictionaryValue* result = new DictionaryValue();
197 result->SetInteger(kBytesWrittenKey, bytes_written); 220 result->SetInteger(kBytesWrittenKey, bytes_written);
198 result_.reset(result); 221 result_.reset(result);
199 } 222 }
200 223
201 bool SocketWriteFunction::Respond() { 224 bool SocketWriteFunction::Respond() {
202 return true; 225 return true;
203 } 226 }
204 227
228 bool SocketRecvFromFunction::Prepare() {
229 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
230 return true;
231 }
232
233 void SocketRecvFromFunction::Work() {
234 // TODO(miket): this is an arbitrary number. Can we come up with one that
235 // makes sense?
236 const int buffer_len = 2048;
237 scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(buffer_len));
238 Socket* socket = controller()->GetSocket(socket_id_);
239 int bytes_read = -1;
240 std::string ip_address_str;
241 int port = 0;
242 if (socket) {
243 bytes_read = socket->RecvFrom(io_buffer, buffer_len, &address_);
244 }
245
246 // TODO(miket): the buffer-to-array functionality appears twice, once here
247 // and once in socket.cc. When serial etc. is converted over, it'll appear
248 // there, too. What's a good single place for it to live? Keep in mind that
249 // this is short-term code, to be replaced with ArrayBuffer code.
250 DictionaryValue* result = new DictionaryValue();
251 ListValue* data_value = new ListValue();
252 if (bytes_read > 0) {
253 Socket::IPEndPointToStringAndPort(address_, &ip_address_str, &port);
254 size_t bytes_size = static_cast<size_t>(bytes_read);
255 const char* io_buffer_start = io_buffer->data();
256 for (size_t i = 0; i < bytes_size; ++i) {
257 data_value->Set(i, Value::CreateIntegerValue(io_buffer_start[i]));
258 }
259 }
260 result->Set(kDataKey, data_value);
261 result->SetString(kAddressKey, ip_address_str);
262 result->SetInteger(kPortKey, port);
263 result_.reset(result);
264 }
265
266 bool SocketRecvFromFunction::Respond() {
267 return true;
268 }
269
270 SocketSendToFunction::SocketSendToFunction()
271 : socket_id_(0),
272 io_buffer_(NULL) {
273 }
274
275 SocketSendToFunction::~SocketSendToFunction() {
276 }
277
278 bool SocketSendToFunction::Prepare() {
279 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
280 base::ListValue *data_list_value;
281 EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &data_list_value));
282 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &address_));
283 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_));
284
285 size_t size = data_list_value->GetSize();
286 if (size != 0) {
287 io_buffer_ = new net::IOBufferWithSize(size);
288 uint8* data_buffer =
289 reinterpret_cast<uint8*>(io_buffer_->data());
290 for (size_t i = 0; i < size; ++i) {
291 int int_value = -1;
292 data_list_value->GetInteger(i, &int_value);
293 DCHECK(int_value < 256);
294 DCHECK(int_value >= 0);
295 uint8 truncated_int = static_cast<uint8>(int_value);
296 *data_buffer++ = truncated_int;
297 }
298 }
299 return true;
300 }
301
302 void SocketSendToFunction::Work() {
303 int bytes_written = -1;
304 Socket* socket = controller()->GetSocket(socket_id_);
305 if (socket) {
306 bytes_written = socket->SendTo(io_buffer_, io_buffer_->size(), address_,
307 port_);
308 } else {
309 error_ = kSocketNotFoundError;
310 }
311
312 DictionaryValue* result = new DictionaryValue();
313 result->SetInteger(kBytesWrittenKey, bytes_written);
314 result_.reset(result);
315 }
316
317 bool SocketSendToFunction::Respond() {
318 return true;
319 }
320
205 } // namespace extensions 321 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698