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

Side by Side Diff: components/usb_service/usb_device_handle.cc

Issue 236203019: Move UsbService to its own component. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Move usb_service component symbols into usb_service namespace Created 6 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 | Annotate | Revision Log
« no previous file with comments | « components/usb_service/usb_device_handle.h ('k') | components/usb_service/usb_interface.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/usb/usb_device_handle.h" 5 #include "components/usb_service/usb_device_handle.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "chrome/browser/usb/usb_context.h" 14 #include "components/usb_service/usb_context.h"
15 #include "chrome/browser/usb/usb_device.h" 15 #include "components/usb_service/usb_device.h"
16 #include "chrome/browser/usb/usb_interface.h" 16 #include "components/usb_service/usb_interface.h"
17 #include "chrome/browser/usb/usb_service.h" 17 #include "components/usb_service/usb_service.h"
18 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "third_party/libusb/src/libusb/libusb.h" 19 #include "third_party/libusb/src/libusb/libusb.h"
20 20
21 using content::BrowserThread; 21 using content::BrowserThread;
22 void HandleTransferCompletion(PlatformUsbTransferHandle transfer); 22
23 namespace usb_service {
24
25 void HandleTransferCompletion(usb_service::PlatformUsbTransferHandle transfer);
23 26
24 namespace { 27 namespace {
25 28
26 static uint8 ConvertTransferDirection( 29 static uint8 ConvertTransferDirection(const UsbEndpointDirection direction) {
27 const UsbEndpointDirection direction) {
28 switch (direction) { 30 switch (direction) {
29 case USB_DIRECTION_INBOUND: 31 case USB_DIRECTION_INBOUND:
30 return LIBUSB_ENDPOINT_IN; 32 return LIBUSB_ENDPOINT_IN;
31 case USB_DIRECTION_OUTBOUND: 33 case USB_DIRECTION_OUTBOUND:
32 return LIBUSB_ENDPOINT_OUT; 34 return LIBUSB_ENDPOINT_OUT;
33 default: 35 default:
34 NOTREACHED(); 36 NOTREACHED();
35 return LIBUSB_ENDPOINT_IN; 37 return LIBUSB_ENDPOINT_IN;
36 } 38 }
37 } 39 }
38 40
39 static uint8 CreateRequestType(const UsbEndpointDirection direction, 41 static uint8 CreateRequestType(
42 const UsbEndpointDirection direction,
40 const UsbDeviceHandle::TransferRequestType request_type, 43 const UsbDeviceHandle::TransferRequestType request_type,
41 const UsbDeviceHandle::TransferRecipient recipient) { 44 const UsbDeviceHandle::TransferRecipient recipient) {
42 uint8 result = ConvertTransferDirection(direction); 45 uint8 result = ConvertTransferDirection(direction);
43 46
44 switch (request_type) { 47 switch (request_type) {
45 case UsbDeviceHandle::STANDARD: 48 case UsbDeviceHandle::STANDARD:
46 result |= LIBUSB_REQUEST_TYPE_STANDARD; 49 result |= LIBUSB_REQUEST_TYPE_STANDARD;
47 break; 50 break;
48 case UsbDeviceHandle::CLASS: 51 case UsbDeviceHandle::CLASS:
49 result |= LIBUSB_REQUEST_TYPE_CLASS; 52 result |= LIBUSB_REQUEST_TYPE_CLASS;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 case LIBUSB_TRANSFER_OVERFLOW: 93 case LIBUSB_TRANSFER_OVERFLOW:
91 return USB_TRANSFER_OVERFLOW; 94 return USB_TRANSFER_OVERFLOW;
92 case LIBUSB_TRANSFER_CANCELLED: 95 case LIBUSB_TRANSFER_CANCELLED:
93 return USB_TRANSFER_CANCELLED; 96 return USB_TRANSFER_CANCELLED;
94 default: 97 default:
95 NOTREACHED(); 98 NOTREACHED();
96 return USB_TRANSFER_ERROR; 99 return USB_TRANSFER_ERROR;
97 } 100 }
98 } 101 }
99 102
100 static void LIBUSB_CALL PlatformTransferCompletionCallback( 103 static void LIBUSB_CALL
101 PlatformUsbTransferHandle transfer) { 104 PlatformTransferCompletionCallback(PlatformUsbTransferHandle transfer) {
102 BrowserThread::PostTask(BrowserThread::FILE, 105 BrowserThread::PostTask(BrowserThread::FILE,
103 FROM_HERE, 106 FROM_HERE,
104 base::Bind(HandleTransferCompletion, transfer)); 107 base::Bind(HandleTransferCompletion, transfer));
105 } 108 }
106 109
107 } // namespace 110 } // namespace
108 111
109 void HandleTransferCompletion(PlatformUsbTransferHandle transfer) { 112 void HandleTransferCompletion(PlatformUsbTransferHandle transfer) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
111 UsbDeviceHandle* const device_handle = 114 UsbDeviceHandle* const device_handle =
112 reinterpret_cast<UsbDeviceHandle*>(transfer->user_data); 115 reinterpret_cast<UsbDeviceHandle*>(transfer->user_data);
113 CHECK(device_handle) << "Device handle is closed before transfer finishes."; 116 CHECK(device_handle) << "Device handle is closed before transfer finishes.";
114 device_handle->TransferComplete(transfer); 117 device_handle->TransferComplete(transfer);
115 libusb_free_transfer(transfer); 118 libusb_free_transfer(transfer);
116 } 119 }
117 120
118
119 class UsbDeviceHandle::InterfaceClaimer 121 class UsbDeviceHandle::InterfaceClaimer
120 : public base::RefCountedThreadSafe<UsbDeviceHandle::InterfaceClaimer> { 122 : public base::RefCountedThreadSafe<UsbDeviceHandle::InterfaceClaimer> {
121 public: 123 public:
122 InterfaceClaimer(const scoped_refptr<UsbDeviceHandle> handle, 124 InterfaceClaimer(const scoped_refptr<UsbDeviceHandle> handle,
123 const int interface_number); 125 const int interface_number);
124 126
125 bool Claim() const; 127 bool Claim() const;
126 128
127 int alternate_setting() const { return alternate_setting_; } 129 int alternate_setting() const { return alternate_setting_; }
128 void set_alternate_setting(const int alternate_setting) { 130 void set_alternate_setting(const int alternate_setting) {
129 alternate_setting_ = alternate_setting; 131 alternate_setting_ = alternate_setting;
130 } 132 }
131 133
132 private: 134 private:
133 friend class UsbDevice; 135 friend class UsbDevice;
134 friend class base::RefCountedThreadSafe<InterfaceClaimer>; 136 friend class base::RefCountedThreadSafe<InterfaceClaimer>;
135 ~InterfaceClaimer(); 137 ~InterfaceClaimer();
136 138
137 const scoped_refptr<UsbDeviceHandle> handle_; 139 const scoped_refptr<UsbDeviceHandle> handle_;
138 const int interface_number_; 140 const int interface_number_;
139 int alternate_setting_; 141 int alternate_setting_;
140 142
141 DISALLOW_COPY_AND_ASSIGN(InterfaceClaimer); 143 DISALLOW_COPY_AND_ASSIGN(InterfaceClaimer);
142 }; 144 };
143 145
144 UsbDeviceHandle::InterfaceClaimer::InterfaceClaimer( 146 UsbDeviceHandle::InterfaceClaimer::InterfaceClaimer(
145 const scoped_refptr<UsbDeviceHandle> handle, const int interface_number) 147 const scoped_refptr<UsbDeviceHandle> handle,
148 const int interface_number)
146 : handle_(handle), 149 : handle_(handle),
147 interface_number_(interface_number), 150 interface_number_(interface_number),
148 alternate_setting_(0) { 151 alternate_setting_(0) {
149 } 152 }
150 153
151 UsbDeviceHandle::InterfaceClaimer::~InterfaceClaimer() { 154 UsbDeviceHandle::InterfaceClaimer::~InterfaceClaimer() {
152 libusb_release_interface(handle_->handle(), interface_number_); 155 libusb_release_interface(handle_->handle(), interface_number_);
153 } 156 }
154 157
155 bool UsbDeviceHandle::InterfaceClaimer::Claim() const { 158 bool UsbDeviceHandle::InterfaceClaimer::Claim() const {
156 return libusb_claim_interface(handle_->handle(), interface_number_) == 0; 159 return libusb_claim_interface(handle_->handle(), interface_number_) == 0;
157 } 160 }
158 161
159 struct UsbDeviceHandle::Transfer { 162 struct UsbDeviceHandle::Transfer {
160 Transfer(); 163 Transfer();
161 ~Transfer(); 164 ~Transfer();
162 165
163 UsbTransferType transfer_type; 166 UsbTransferType transfer_type;
164 scoped_refptr<net::IOBuffer> buffer; 167 scoped_refptr<net::IOBuffer> buffer;
165 scoped_refptr<UsbDeviceHandle::InterfaceClaimer> claimed_interface; 168 scoped_refptr<UsbDeviceHandle::InterfaceClaimer> claimed_interface;
166 scoped_refptr<base::MessageLoopProxy> message_loop_proxy; 169 scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
167 size_t length; 170 size_t length;
168 UsbTransferCallback callback; 171 UsbTransferCallback callback;
169 }; 172 };
170 173
171 UsbDeviceHandle::Transfer::Transfer() 174 UsbDeviceHandle::Transfer::Transfer()
172 : transfer_type(USB_TRANSFER_CONTROL), 175 : transfer_type(USB_TRANSFER_CONTROL), length(0) {
173 length(0) {
174 } 176 }
175 177
176 UsbDeviceHandle::Transfer::~Transfer() {} 178 UsbDeviceHandle::Transfer::~Transfer() {
179 }
177 180
178 UsbDeviceHandle::UsbDeviceHandle( 181 UsbDeviceHandle::UsbDeviceHandle(scoped_refptr<UsbContext> context,
179 scoped_refptr<UsbContext> context, 182 UsbDevice* device,
180 UsbDevice* device, 183 PlatformUsbDeviceHandle handle,
181 PlatformUsbDeviceHandle handle, 184 scoped_refptr<UsbConfigDescriptor> interfaces)
182 scoped_refptr<UsbConfigDescriptor> interfaces)
183 : device_(device), 185 : device_(device),
184 handle_(handle), 186 handle_(handle),
185 interfaces_(interfaces), 187 interfaces_(interfaces),
186 context_(context) { 188 context_(context) {
187 DCHECK(thread_checker_.CalledOnValidThread()); 189 DCHECK(thread_checker_.CalledOnValidThread());
188 DCHECK(handle) << "Cannot create device with NULL handle."; 190 DCHECK(handle) << "Cannot create device with NULL handle.";
189 DCHECK(interfaces_) << "Unabled to list interfaces"; 191 DCHECK(interfaces_) << "Unabled to list interfaces";
190 } 192 }
191 193
192 UsbDeviceHandle::UsbDeviceHandle() : device_(NULL), handle_(NULL) { 194 UsbDeviceHandle::UsbDeviceHandle() : device_(NULL), handle_(NULL) {
(...skipping 19 matching lines...) Expand all
212 void UsbDeviceHandle::TransferComplete(PlatformUsbTransferHandle handle) { 214 void UsbDeviceHandle::TransferComplete(PlatformUsbTransferHandle handle) {
213 DCHECK(ContainsKey(transfers_, handle)) << "Missing transfer completed"; 215 DCHECK(ContainsKey(transfers_, handle)) << "Missing transfer completed";
214 216
215 Transfer transfer = transfers_[handle]; 217 Transfer transfer = transfers_[handle];
216 transfers_.erase(handle); 218 transfers_.erase(handle);
217 219
218 DCHECK_GE(handle->actual_length, 0) << "Negative actual length received"; 220 DCHECK_GE(handle->actual_length, 0) << "Negative actual length received";
219 size_t actual_length = 221 size_t actual_length =
220 static_cast<size_t>(std::max(handle->actual_length, 0)); 222 static_cast<size_t>(std::max(handle->actual_length, 0));
221 223
222 DCHECK(transfer.length >= actual_length) << 224 DCHECK(transfer.length >= actual_length)
223 "data too big for our buffer (libusb failure?)"; 225 << "data too big for our buffer (libusb failure?)";
224 226
225 scoped_refptr<net::IOBuffer> buffer = transfer.buffer; 227 scoped_refptr<net::IOBuffer> buffer = transfer.buffer;
226 switch (transfer.transfer_type) { 228 switch (transfer.transfer_type) {
227 case USB_TRANSFER_CONTROL: 229 case USB_TRANSFER_CONTROL:
228 // If the transfer is a control transfer we do not expose the control 230 // If the transfer is a control transfer we do not expose the control
229 // setup header to the caller. This logic strips off the header if 231 // setup header to the caller. This logic strips off the header if
230 // present before invoking the callback provided with the transfer. 232 // present before invoking the callback provided with the transfer.
231 if (actual_length > 0) { 233 if (actual_length > 0) {
232 CHECK(transfer.length >= LIBUSB_CONTROL_SETUP_SIZE) << 234 CHECK(transfer.length >= LIBUSB_CONTROL_SETUP_SIZE)
233 "buffer was not correctly set: too small for the control header"; 235 << "buffer was not correctly set: too small for the control header";
234 236
235 if (transfer.length >= actual_length && 237 if (transfer.length >= actual_length &&
236 actual_length >= LIBUSB_CONTROL_SETUP_SIZE) { 238 actual_length >= LIBUSB_CONTROL_SETUP_SIZE) {
237 // If the payload is zero bytes long, pad out the allocated buffer 239 // If the payload is zero bytes long, pad out the allocated buffer
238 // size to one byte so that an IOBuffer of that size can be allocated. 240 // size to one byte so that an IOBuffer of that size can be allocated.
239 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( 241 scoped_refptr<net::IOBuffer> resized_buffer =
240 std::max(actual_length, static_cast<size_t>(1))); 242 new net::IOBuffer(static_cast<int>(
243 std::max(actual_length, static_cast<size_t>(1))));
241 memcpy(resized_buffer->data(), 244 memcpy(resized_buffer->data(),
242 buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, 245 buffer->data() + LIBUSB_CONTROL_SETUP_SIZE,
243 actual_length); 246 actual_length);
244 buffer = resized_buffer; 247 buffer = resized_buffer;
245 } 248 }
246 } 249 }
247 break; 250 break;
248 251
249 case USB_TRANSFER_ISOCHRONOUS: 252 case USB_TRANSFER_ISOCHRONOUS:
250 // Isochronous replies might carry data in the different isoc packets even 253 // Isochronous replies might carry data in the different isoc packets even
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 ConvertTransferStatus(handle->status), 291 ConvertTransferStatus(handle->status),
289 buffer, 292 buffer,
290 actual_length)); 293 actual_length));
291 294
292 // Must release interface first before actually delete this. 295 // Must release interface first before actually delete this.
293 transfer.claimed_interface = NULL; 296 transfer.claimed_interface = NULL;
294 } 297 }
295 298
296 bool UsbDeviceHandle::ClaimInterface(const int interface_number) { 299 bool UsbDeviceHandle::ClaimInterface(const int interface_number) {
297 DCHECK(thread_checker_.CalledOnValidThread()); 300 DCHECK(thread_checker_.CalledOnValidThread());
298 if (!device_) return false; 301 if (!device_)
299 if (ContainsKey(claimed_interfaces_, interface_number)) return true; 302 return false;
303 if (ContainsKey(claimed_interfaces_, interface_number))
304 return true;
300 305
301 scoped_refptr<InterfaceClaimer> claimer = 306 scoped_refptr<InterfaceClaimer> claimer =
302 new InterfaceClaimer(this, interface_number); 307 new InterfaceClaimer(this, interface_number);
303 308
304 if (claimer->Claim()) { 309 if (claimer->Claim()) {
305 claimed_interfaces_[interface_number]= claimer; 310 claimed_interfaces_[interface_number] = claimer;
306 RefreshEndpointMap(); 311 RefreshEndpointMap();
307 return true; 312 return true;
308 } 313 }
309 return false; 314 return false;
310 } 315 }
311 316
312 bool UsbDeviceHandle::ReleaseInterface(const int interface_number) { 317 bool UsbDeviceHandle::ReleaseInterface(const int interface_number) {
313 DCHECK(thread_checker_.CalledOnValidThread()); 318 DCHECK(thread_checker_.CalledOnValidThread());
314 if (!device_) return false; 319 if (!device_)
315 if (!ContainsKey(claimed_interfaces_, interface_number)) return false; 320 return false;
321 if (!ContainsKey(claimed_interfaces_, interface_number))
322 return false;
316 323
317 // Cancel all the transfers on that interface. 324 // Cancel all the transfers on that interface.
318 InterfaceClaimer* interface_claimer = 325 InterfaceClaimer* interface_claimer =
319 claimed_interfaces_[interface_number].get(); 326 claimed_interfaces_[interface_number].get();
320 for (TransferMap::iterator it = transfers_.begin(); 327 for (TransferMap::iterator it = transfers_.begin(); it != transfers_.end();
321 it != transfers_.end(); ++it) { 328 ++it) {
322 if (it->second.claimed_interface.get() == interface_claimer) 329 if (it->second.claimed_interface.get() == interface_claimer)
323 libusb_cancel_transfer(it->first); 330 libusb_cancel_transfer(it->first);
324 } 331 }
325 claimed_interfaces_.erase(interface_number); 332 claimed_interfaces_.erase(interface_number);
326 333
327 RefreshEndpointMap(); 334 RefreshEndpointMap();
328 return true; 335 return true;
329 } 336 }
330 337
331 bool UsbDeviceHandle::SetInterfaceAlternateSetting( 338 bool UsbDeviceHandle::SetInterfaceAlternateSetting(
332 const int interface_number, 339 const int interface_number,
333 const int alternate_setting) { 340 const int alternate_setting) {
334 DCHECK(thread_checker_.CalledOnValidThread()); 341 DCHECK(thread_checker_.CalledOnValidThread());
335 if (!device_) return false; 342 if (!device_)
336 if (!ContainsKey(claimed_interfaces_, interface_number)) return false; 343 return false;
337 const int rv = libusb_set_interface_alt_setting(handle_, 344 if (!ContainsKey(claimed_interfaces_, interface_number))
338 interface_number, alternate_setting); 345 return false;
346 const int rv = libusb_set_interface_alt_setting(
347 handle_, interface_number, alternate_setting);
339 if (rv == 0) { 348 if (rv == 0) {
340 claimed_interfaces_[interface_number]-> 349 claimed_interfaces_[interface_number]->set_alternate_setting(
341 set_alternate_setting(alternate_setting); 350 alternate_setting);
342 RefreshEndpointMap(); 351 RefreshEndpointMap();
343 return true; 352 return true;
344 } 353 }
345 return false; 354 return false;
346 } 355 }
347 356
348 bool UsbDeviceHandle::ResetDevice() { 357 bool UsbDeviceHandle::ResetDevice() {
349 DCHECK(thread_checker_.CalledOnValidThread()); 358 DCHECK(thread_checker_.CalledOnValidThread());
350 if (!device_) return false; 359 if (!device_)
360 return false;
351 361
352 return libusb_reset_device(handle_) == 0; 362 return libusb_reset_device(handle_) == 0;
353 } 363 }
354 364
355 bool UsbDeviceHandle::GetSerial(base::string16* serial) { 365 bool UsbDeviceHandle::GetSerial(base::string16* serial) {
356 DCHECK(thread_checker_.CalledOnValidThread()); 366 DCHECK(thread_checker_.CalledOnValidThread());
357 PlatformUsbDevice device = libusb_get_device(handle_); 367 PlatformUsbDevice device = libusb_get_device(handle_);
358 libusb_device_descriptor desc; 368 libusb_device_descriptor desc;
359 369
360 if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS) 370 if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS)
361 return false; 371 return false;
362 372
363 if (desc.iSerialNumber == 0) 373 if (desc.iSerialNumber == 0)
364 return false; 374 return false;
365 375
366 // Getting supported language ID. 376 // Getting supported language ID.
367 uint16 langid[128] = { 0 }; 377 uint16 langid[128] = {0};
368 378
369 int size = libusb_get_string_descriptor( 379 int size =
370 handle_, 0, 0, 380 libusb_get_string_descriptor(handle_,
371 reinterpret_cast<unsigned char*>(&langid[0]), sizeof(langid)); 381 0,
382 0,
383 reinterpret_cast<unsigned char*>(&langid[0]),
384 sizeof(langid));
372 if (size < 0) 385 if (size < 0)
373 return false; 386 return false;
374 387
375 int language_count = (size - 2) / 2; 388 int language_count = (size - 2) / 2;
376 389
377 for (int i = 1; i <= language_count; ++i) { 390 for (int i = 1; i <= language_count; ++i) {
378 // Get the string using language ID. 391 // Get the string using language ID.
379 base::char16 text[256] = { 0 }; 392 base::char16 text[256] = {0};
380 size = libusb_get_string_descriptor( 393 size =
381 handle_, desc.iSerialNumber, langid[i], 394 libusb_get_string_descriptor(handle_,
382 reinterpret_cast<unsigned char*>(&text[0]), sizeof(text)); 395 desc.iSerialNumber,
396 langid[i],
397 reinterpret_cast<unsigned char*>(&text[0]),
398 sizeof(text));
383 if (size <= 2) 399 if (size <= 2)
384 continue; 400 continue;
385 if ((text[0] >> 8) != LIBUSB_DT_STRING) 401 if ((text[0] >> 8) != LIBUSB_DT_STRING)
386 continue; 402 continue;
387 if ((text[0] & 255) > size) 403 if ((text[0] & 255) > size)
388 continue; 404 continue;
389 405
390 size = size / 2 - 1; 406 size = size / 2 - 1;
391 *serial = base::string16(text + 1, size); 407 *serial = base::string16(text + 1, size);
392 return true; 408 return true;
393 } 409 }
394 return false; 410 return false;
395 } 411 }
396 412
397 void UsbDeviceHandle::ControlTransfer(const UsbEndpointDirection direction, 413 void UsbDeviceHandle::ControlTransfer(const UsbEndpointDirection direction,
398 const TransferRequestType request_type, const TransferRecipient recipient, 414 const TransferRequestType request_type,
399 const uint8 request, const uint16 value, const uint16 index, 415 const TransferRecipient recipient,
400 net::IOBuffer* buffer, const size_t length, const unsigned int timeout, 416 const uint8 request,
401 const UsbTransferCallback& callback) { 417 const uint16 value,
418 const uint16 index,
419 net::IOBuffer* buffer,
420 const size_t length,
421 const unsigned int timeout,
422 const UsbTransferCallback& callback) {
402 if (!device_) { 423 if (!device_) {
403 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); 424 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
404 return; 425 return;
405 } 426 }
406 427
407 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; 428 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length;
408 scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize( 429 scoped_refptr<net::IOBuffer> resized_buffer(
409 resized_length)); 430 new net::IOBufferWithSize(static_cast<int>(resized_length)));
410 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), 431 if (!resized_buffer) {
411 length); 432 callback.Run(USB_TRANSFER_ERROR, buffer, 0);
433 return;
434 }
435 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE,
436 buffer->data(),
437 static_cast<int>(length));
412 438
413 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0); 439 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0);
414 const uint8 converted_type = CreateRequestType(direction, request_type, 440 const uint8 converted_type =
415 recipient); 441 CreateRequestType(direction, request_type, recipient);
416 libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()), 442 libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()),
417 converted_type, request, value, index, length); 443 converted_type,
418 libusb_fill_control_transfer( 444 request,
419 transfer, 445 value,
420 handle_, 446 index,
421 reinterpret_cast<uint8*>(resized_buffer->data()), 447 static_cast<int16>(length));
422 PlatformTransferCompletionCallback, 448 libusb_fill_control_transfer(transfer,
423 this, 449 handle_,
424 timeout); 450 reinterpret_cast<uint8*>(resized_buffer->data()),
451 PlatformTransferCompletionCallback,
452 this,
453 timeout);
425 454
426 BrowserThread::PostTask( 455 BrowserThread::PostTask(BrowserThread::FILE,
427 BrowserThread::FILE, 456 FROM_HERE,
428 FROM_HERE, 457 base::Bind(&UsbDeviceHandle::SubmitTransfer,
429 base::Bind(&UsbDeviceHandle::SubmitTransfer, 458 this,
430 this, 459 transfer,
431 transfer, 460 USB_TRANSFER_CONTROL,
432 USB_TRANSFER_CONTROL, 461 resized_buffer,
433 resized_buffer, 462 resized_length,
434 resized_length, 463 base::MessageLoopProxy::current(),
435 base::MessageLoopProxy::current(), 464 callback));
436 callback));
437 } 465 }
438 466
439 void UsbDeviceHandle::BulkTransfer(const UsbEndpointDirection direction, 467 void UsbDeviceHandle::BulkTransfer(const UsbEndpointDirection direction,
440 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, 468 const uint8 endpoint,
441 const unsigned int timeout, const UsbTransferCallback& callback) { 469 net::IOBuffer* buffer,
470 const size_t length,
471 const unsigned int timeout,
472 const UsbTransferCallback& callback) {
442 if (!device_) { 473 if (!device_) {
443 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); 474 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
444 return; 475 return;
445 } 476 }
446 477
447 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0); 478 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0);
448 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; 479 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
449 libusb_fill_bulk_transfer(transfer, handle_, new_endpoint, 480 libusb_fill_bulk_transfer(transfer,
450 reinterpret_cast<uint8*>(buffer->data()), length, 481 handle_,
451 PlatformTransferCompletionCallback, this, timeout); 482 new_endpoint,
483 reinterpret_cast<uint8*>(buffer->data()),
484 static_cast<int>(length),
485 PlatformTransferCompletionCallback,
486 this,
487 timeout);
452 488
453 BrowserThread::PostTask( 489 BrowserThread::PostTask(BrowserThread::FILE,
454 BrowserThread::FILE, 490 FROM_HERE,
455 FROM_HERE, 491 base::Bind(&UsbDeviceHandle::SubmitTransfer,
456 base::Bind(&UsbDeviceHandle::SubmitTransfer, 492 this,
457 this, 493 transfer,
458 transfer, 494 USB_TRANSFER_BULK,
459 USB_TRANSFER_BULK, 495 make_scoped_refptr(buffer),
460 make_scoped_refptr(buffer), 496 length,
461 length, 497 base::MessageLoopProxy::current(),
462 base::MessageLoopProxy::current(), 498 callback));
463 callback));
464 } 499 }
465 500
466 void UsbDeviceHandle::InterruptTransfer(const UsbEndpointDirection direction, 501 void UsbDeviceHandle::InterruptTransfer(const UsbEndpointDirection direction,
467 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, 502 const uint8 endpoint,
468 const unsigned int timeout, const UsbTransferCallback& callback) { 503 net::IOBuffer* buffer,
504 const size_t length,
505 const unsigned int timeout,
506 const UsbTransferCallback& callback) {
469 if (!device_) { 507 if (!device_) {
470 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); 508 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
471 return; 509 return;
472 } 510 }
473 511
474 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0); 512 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0);
475 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; 513 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
476 libusb_fill_interrupt_transfer(transfer, handle_, new_endpoint, 514 libusb_fill_interrupt_transfer(transfer,
477 reinterpret_cast<uint8*>(buffer->data()), length, 515 handle_,
478 PlatformTransferCompletionCallback, this, timeout); 516 new_endpoint,
479 BrowserThread::PostTask( 517 reinterpret_cast<uint8*>(buffer->data()),
480 BrowserThread::FILE, 518 static_cast<int>(length),
481 FROM_HERE, 519 PlatformTransferCompletionCallback,
482 base::Bind(&UsbDeviceHandle::SubmitTransfer, 520 this,
483 this, 521 timeout);
484 transfer, 522 BrowserThread::PostTask(BrowserThread::FILE,
485 USB_TRANSFER_INTERRUPT, 523 FROM_HERE,
486 make_scoped_refptr(buffer), 524 base::Bind(&UsbDeviceHandle::SubmitTransfer,
487 length, 525 this,
488 base::MessageLoopProxy::current(), 526 transfer,
489 callback)); 527 USB_TRANSFER_INTERRUPT,
528 make_scoped_refptr(buffer),
529 length,
530 base::MessageLoopProxy::current(),
531 callback));
490 } 532 }
491 533
492 void UsbDeviceHandle::IsochronousTransfer(const UsbEndpointDirection direction, 534 void UsbDeviceHandle::IsochronousTransfer(const UsbEndpointDirection direction,
493 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, 535 const uint8 endpoint,
494 const unsigned int packets, const unsigned int packet_length, 536 net::IOBuffer* buffer,
495 const unsigned int timeout, const UsbTransferCallback& callback) { 537 const size_t length,
538 const unsigned int packets,
539 const unsigned int packet_length,
540 const unsigned int timeout,
541 const UsbTransferCallback& callback) {
496 if (!device_) { 542 if (!device_) {
497 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); 543 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
498 return; 544 return;
499 } 545 }
500 546
501 const uint64 total_length = packets * packet_length; 547 const uint64 total_length = packets * packet_length;
502 CHECK(packets <= length && total_length <= length) << 548 CHECK(packets <= length && total_length <= length)
503 "transfer length is too small"; 549 << "transfer length is too small";
504 550
505 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(packets); 551 PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(packets);
506 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; 552 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
507 libusb_fill_iso_transfer(transfer, handle_, new_endpoint, 553 libusb_fill_iso_transfer(transfer,
508 reinterpret_cast<uint8*>(buffer->data()), length, packets, 554 handle_,
509 PlatformTransferCompletionCallback, this, timeout); 555 new_endpoint,
556 reinterpret_cast<uint8*>(buffer->data()),
557 static_cast<int>(length),
558 packets,
559 PlatformTransferCompletionCallback,
560 this,
561 timeout);
510 libusb_set_iso_packet_lengths(transfer, packet_length); 562 libusb_set_iso_packet_lengths(transfer, packet_length);
511 563
512 BrowserThread::PostTask( 564 BrowserThread::PostTask(BrowserThread::FILE,
513 BrowserThread::FILE, 565 FROM_HERE,
514 FROM_HERE, 566 base::Bind(&UsbDeviceHandle::SubmitTransfer,
515 base::Bind(&UsbDeviceHandle::SubmitTransfer, 567 this,
516 this, 568 transfer,
517 transfer, 569 USB_TRANSFER_ISOCHRONOUS,
518 USB_TRANSFER_ISOCHRONOUS, 570 make_scoped_refptr(buffer),
519 make_scoped_refptr(buffer), 571 length,
520 length, 572 base::MessageLoopProxy::current(),
521 base::MessageLoopProxy::current(), 573 callback));
522 callback));
523 } 574 }
524 575
525 void UsbDeviceHandle::RefreshEndpointMap() { 576 void UsbDeviceHandle::RefreshEndpointMap() {
526 DCHECK(thread_checker_.CalledOnValidThread()); 577 DCHECK(thread_checker_.CalledOnValidThread());
527 endpoint_map_.clear(); 578 endpoint_map_.clear();
528 for (ClaimedInterfaceMap::iterator it = claimed_interfaces_.begin(); 579 for (ClaimedInterfaceMap::iterator it = claimed_interfaces_.begin();
529 it != claimed_interfaces_.end(); ++it) { 580 it != claimed_interfaces_.end();
581 ++it) {
530 scoped_refptr<const UsbInterfaceAltSettingDescriptor> interface_desc = 582 scoped_refptr<const UsbInterfaceAltSettingDescriptor> interface_desc =
531 interfaces_->GetInterface(it->first)->GetAltSetting( 583 interfaces_->GetInterface(it->first)
532 it->second->alternate_setting()); 584 ->GetAltSetting(it->second->alternate_setting());
533 for (size_t i = 0; i < interface_desc->GetNumEndpoints(); i++) { 585 for (size_t i = 0; i < interface_desc->GetNumEndpoints(); i++) {
534 scoped_refptr<const UsbEndpointDescriptor> endpoint = 586 scoped_refptr<const UsbEndpointDescriptor> endpoint =
535 interface_desc->GetEndpoint(i); 587 interface_desc->GetEndpoint(i);
536 endpoint_map_[endpoint->GetAddress()] = it->first; 588 endpoint_map_[endpoint->GetAddress()] = it->first;
537 } 589 }
538 } 590 }
539 } 591 }
540 592
541 scoped_refptr<UsbDeviceHandle::InterfaceClaimer> 593 scoped_refptr<UsbDeviceHandle::InterfaceClaimer>
542 UsbDeviceHandle::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { 594 UsbDeviceHandle::GetClaimedInterfaceForEndpoint(unsigned char endpoint) {
543 unsigned char address = endpoint & LIBUSB_ENDPOINT_ADDRESS_MASK; 595 unsigned char address = endpoint & LIBUSB_ENDPOINT_ADDRESS_MASK;
544 if (ContainsKey(endpoint_map_, address)) 596 if (ContainsKey(endpoint_map_, address))
545 return claimed_interfaces_[endpoint_map_[address]]; 597 return claimed_interfaces_[endpoint_map_[address]];
546 return NULL; 598 return NULL;
547 } 599 }
548 600
549 void UsbDeviceHandle::SubmitTransfer( 601 void UsbDeviceHandle::SubmitTransfer(
550 PlatformUsbTransferHandle handle, 602 PlatformUsbTransferHandle handle,
551 UsbTransferType transfer_type, 603 UsbTransferType transfer_type,
552 net::IOBuffer* buffer, 604 net::IOBuffer* buffer,
553 const size_t length, 605 const size_t length,
554 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 606 scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
555 const UsbTransferCallback& callback) { 607 const UsbTransferCallback& callback) {
556 DCHECK(thread_checker_.CalledOnValidThread()); 608 DCHECK(thread_checker_.CalledOnValidThread());
557 if (!device_) { 609 if (!device_) {
558 message_loop_proxy->PostTask( 610 message_loop_proxy->PostTask(
559 FROM_HERE, 611 FROM_HERE,
560 base::Bind(callback, USB_TRANSFER_DISCONNECT, 612 base::Bind(
561 make_scoped_refptr(buffer), 0)); 613 callback, USB_TRANSFER_DISCONNECT, make_scoped_refptr(buffer), 0));
562 } 614 }
563 615
564 Transfer transfer; 616 Transfer transfer;
565 transfer.transfer_type = transfer_type; 617 transfer.transfer_type = transfer_type;
566 transfer.buffer = buffer; 618 transfer.buffer = buffer;
567 transfer.length = length; 619 transfer.length = length;
568 transfer.callback = callback; 620 transfer.callback = callback;
569 transfer.message_loop_proxy = message_loop_proxy; 621 transfer.message_loop_proxy = message_loop_proxy;
570 622
571 // It's OK for this method to return NULL. libusb_submit_transfer will fail if 623 // It's OK for this method to return NULL. libusb_submit_transfer will fail if
572 // it requires an interface we didn't claim. 624 // it requires an interface we didn't claim.
573 transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint); 625 transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint);
574 626
575 if (libusb_submit_transfer(handle) == LIBUSB_SUCCESS) { 627 if (libusb_submit_transfer(handle) == LIBUSB_SUCCESS) {
576 transfers_[handle] = transfer; 628 transfers_[handle] = transfer;
577 } else { 629 } else {
578 message_loop_proxy->PostTask( 630 message_loop_proxy->PostTask(
579 FROM_HERE, 631 FROM_HERE,
580 base::Bind(callback, USB_TRANSFER_ERROR, 632 base::Bind(
581 make_scoped_refptr(buffer), 0)); 633 callback, USB_TRANSFER_ERROR, make_scoped_refptr(buffer), 0));
582 } 634 }
583 } 635 }
584 636
585 void UsbDeviceHandle::InternalClose() { 637 void UsbDeviceHandle::InternalClose() {
586 DCHECK(thread_checker_.CalledOnValidThread()); 638 DCHECK(thread_checker_.CalledOnValidThread());
587 if (!device_) return; 639 if (!device_)
640 return;
588 641
589 // Cancel all the transfers. 642 // Cancel all the transfers.
590 for (TransferMap::iterator it = transfers_.begin(); 643 for (TransferMap::iterator it = transfers_.begin(); it != transfers_.end();
591 it != transfers_.end(); ++it) { 644 ++it) {
592 // The callback will be called some time later. 645 // The callback will be called some time later.
593 libusb_cancel_transfer(it->first); 646 libusb_cancel_transfer(it->first);
594 } 647 }
595 648
596 // Attempt-release all the interfaces. 649 // Attempt-release all the interfaces.
597 // It will be retained until the transfer cancellation is finished. 650 // It will be retained until the transfer cancellation is finished.
598 claimed_interfaces_.clear(); 651 claimed_interfaces_.clear();
599 652
600 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to 653 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to
601 // finish. 654 // finish.
602 device_ = NULL; 655 device_ = NULL;
603 } 656 }
657
658 } // namespace usb_service
OLDNEW
« no previous file with comments | « components/usb_service/usb_device_handle.h ('k') | components/usb_service/usb_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698