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

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

Powered by Google App Engine
This is Rietveld 408576698