OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "device/usb/usb_device_handle_impl.h" | 5 #include "device/usb/usb_device_handle_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 << ConvertPlatformUsbErrorToString(rv); | 150 << ConvertPlatformUsbErrorToString(rv); |
151 } | 151 } |
152 return rv == LIBUSB_SUCCESS; | 152 return rv == LIBUSB_SUCCESS; |
153 } | 153 } |
154 | 154 |
155 // This inner class owns the underlying libusb_transfer and may outlast | 155 // This inner class owns the underlying libusb_transfer and may outlast |
156 // the UsbDeviceHandle that created it. | 156 // the UsbDeviceHandle that created it. |
157 class UsbDeviceHandleImpl::Transfer { | 157 class UsbDeviceHandleImpl::Transfer { |
158 public: | 158 public: |
159 static scoped_ptr<Transfer> CreateControlTransfer( | 159 static scoped_ptr<Transfer> CreateControlTransfer( |
160 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
160 uint8 type, | 161 uint8 type, |
161 uint8 request, | 162 uint8 request, |
162 uint16 value, | 163 uint16 value, |
163 uint16 index, | 164 uint16 index, |
164 uint16 length, | 165 uint16 length, |
165 scoped_refptr<net::IOBuffer> buffer, | 166 scoped_refptr<net::IOBuffer> buffer, |
166 unsigned int timeout, | 167 unsigned int timeout, |
168 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
167 const UsbTransferCallback& callback); | 169 const UsbTransferCallback& callback); |
168 static scoped_ptr<Transfer> CreateBulkTransfer( | 170 static scoped_ptr<Transfer> CreateBulkTransfer( |
171 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
169 uint8 endpoint, | 172 uint8 endpoint, |
170 scoped_refptr<net::IOBuffer> buffer, | 173 scoped_refptr<net::IOBuffer> buffer, |
171 int length, | 174 int length, |
172 unsigned int timeout, | 175 unsigned int timeout, |
176 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
173 const UsbTransferCallback& callback); | 177 const UsbTransferCallback& callback); |
174 static scoped_ptr<Transfer> CreateInterruptTransfer( | 178 static scoped_ptr<Transfer> CreateInterruptTransfer( |
179 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
175 uint8 endpoint, | 180 uint8 endpoint, |
176 scoped_refptr<net::IOBuffer> buffer, | 181 scoped_refptr<net::IOBuffer> buffer, |
177 int length, | 182 int length, |
178 unsigned int timeout, | 183 unsigned int timeout, |
184 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
179 const UsbTransferCallback& callback); | 185 const UsbTransferCallback& callback); |
180 static scoped_ptr<Transfer> CreateIsochronousTransfer( | 186 static scoped_ptr<Transfer> CreateIsochronousTransfer( |
187 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
181 uint8 endpoint, | 188 uint8 endpoint, |
182 scoped_refptr<net::IOBuffer> buffer, | 189 scoped_refptr<net::IOBuffer> buffer, |
183 size_t length, | 190 size_t length, |
184 unsigned int packets, | 191 unsigned int packets, |
185 unsigned int packet_length, | 192 unsigned int packet_length, |
186 unsigned int timeout, | 193 unsigned int timeout, |
194 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
187 const UsbTransferCallback& callback); | 195 const UsbTransferCallback& callback); |
188 | 196 |
189 ~Transfer(); | 197 ~Transfer(); |
190 | 198 |
191 bool Submit(base::WeakPtr<UsbDeviceHandleImpl> device_handle); | 199 void Submit(); |
192 void Cancel(); | 200 void Cancel(); |
193 void ProcessCompletion(); | 201 void ProcessCompletion(); |
194 void Complete(UsbTransferStatus status, size_t bytes_transferred); | 202 void TransferComplete(UsbTransferStatus status, size_t bytes_transferred); |
195 | 203 |
196 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const { | 204 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const { |
197 return claimed_interface_.get(); | 205 return claimed_interface_.get(); |
198 } | 206 } |
199 | 207 |
200 private: | 208 private: |
201 Transfer(UsbTransferType transfer_type, | 209 Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle, |
210 scoped_refptr<InterfaceClaimer> claimed_interface, | |
211 UsbTransferType transfer_type, | |
202 scoped_refptr<net::IOBuffer> buffer, | 212 scoped_refptr<net::IOBuffer> buffer, |
203 size_t length, | 213 size_t length, |
214 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
204 const UsbTransferCallback& callback); | 215 const UsbTransferCallback& callback); |
205 | 216 |
206 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle); | 217 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle); |
207 | 218 |
208 UsbTransferType transfer_type_; | 219 UsbTransferType transfer_type_; |
209 base::WeakPtr<UsbDeviceHandleImpl> device_handle_; | 220 scoped_refptr<UsbDeviceHandleImpl> device_handle_; |
210 PlatformUsbTransferHandle platform_transfer_; | 221 PlatformUsbTransferHandle platform_transfer_; |
211 scoped_refptr<net::IOBuffer> buffer_; | 222 scoped_refptr<net::IOBuffer> buffer_; |
212 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; | 223 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; |
213 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
214 size_t length_; | 224 size_t length_; |
215 bool cancelled_; | 225 bool cancelled_; |
226 scoped_refptr<base::SequencedTaskRunner> task_runner_; | |
216 UsbTransferCallback callback_; | 227 UsbTransferCallback callback_; |
217 scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_; | |
218 }; | 228 }; |
219 | 229 |
220 // static | 230 // static |
221 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 231 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
222 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( | 232 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( |
233 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
223 uint8 type, | 234 uint8 type, |
224 uint8 request, | 235 uint8 request, |
225 uint16 value, | 236 uint16 value, |
226 uint16 index, | 237 uint16 index, |
227 uint16 length, | 238 uint16 length, |
228 scoped_refptr<net::IOBuffer> buffer, | 239 scoped_refptr<net::IOBuffer> buffer, |
229 unsigned int timeout, | 240 unsigned int timeout, |
241 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
230 const UsbTransferCallback& callback) { | 242 const UsbTransferCallback& callback) { |
231 scoped_ptr<Transfer> transfer(new Transfer(USB_TRANSFER_CONTROL, buffer, | 243 scoped_ptr<Transfer> transfer( |
232 length + LIBUSB_CONTROL_SETUP_SIZE, | 244 new Transfer(device_handle, nullptr, USB_TRANSFER_CONTROL, buffer, |
233 callback)); | 245 length + LIBUSB_CONTROL_SETUP_SIZE, task_runner, callback)); |
234 | 246 |
235 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 247 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
236 if (!transfer->platform_transfer_) { | 248 if (!transfer->platform_transfer_) { |
237 USB_LOG(ERROR) << "Failed to allocate control transfer."; | 249 USB_LOG(ERROR) << "Failed to allocate control transfer."; |
238 return nullptr; | 250 return nullptr; |
239 } | 251 } |
240 | 252 |
241 libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type, | 253 libusb_fill_control_setup(reinterpret_cast<uint8*>(buffer->data()), type, |
242 request, value, index, length); | 254 request, value, index, length); |
243 libusb_fill_control_transfer(transfer->platform_transfer_, | 255 libusb_fill_control_transfer(transfer->platform_transfer_, |
244 nullptr, /* filled in by Submit() */ | 256 device_handle->handle_, |
245 reinterpret_cast<uint8*>(buffer->data()), | 257 reinterpret_cast<uint8*>(buffer->data()), |
246 &UsbDeviceHandleImpl::Transfer::PlatformCallback, | 258 &UsbDeviceHandleImpl::Transfer::PlatformCallback, |
247 transfer.get(), timeout); | 259 transfer.get(), timeout); |
248 | 260 |
249 return transfer.Pass(); | 261 return transfer.Pass(); |
250 } | 262 } |
251 | 263 |
252 // static | 264 // static |
253 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 265 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
254 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( | 266 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( |
267 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
255 uint8 endpoint, | 268 uint8 endpoint, |
256 scoped_refptr<net::IOBuffer> buffer, | 269 scoped_refptr<net::IOBuffer> buffer, |
257 int length, | 270 int length, |
258 unsigned int timeout, | 271 unsigned int timeout, |
272 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
259 const UsbTransferCallback& callback) { | 273 const UsbTransferCallback& callback) { |
260 scoped_ptr<Transfer> transfer( | 274 scoped_ptr<Transfer> transfer(new Transfer( |
261 new Transfer(USB_TRANSFER_BULK, buffer, length, callback)); | 275 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
276 USB_TRANSFER_BULK, buffer, length, task_runner, callback)); | |
262 | 277 |
263 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 278 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
264 if (!transfer->platform_transfer_) { | 279 if (!transfer->platform_transfer_) { |
265 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; | 280 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; |
266 return nullptr; | 281 return nullptr; |
267 } | 282 } |
268 | 283 |
269 libusb_fill_bulk_transfer(transfer->platform_transfer_, | 284 libusb_fill_bulk_transfer( |
270 nullptr, /* filled in by Submit() */ | 285 transfer->platform_transfer_, device_handle->handle_, endpoint, |
271 endpoint, reinterpret_cast<uint8*>(buffer->data()), | 286 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length), |
272 static_cast<int>(length), | 287 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), |
273 &UsbDeviceHandleImpl::Transfer::PlatformCallback, | 288 timeout); |
274 transfer.get(), timeout); | |
275 | 289 |
276 return transfer.Pass(); | 290 return transfer.Pass(); |
277 } | 291 } |
278 | 292 |
279 // static | 293 // static |
280 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 294 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
281 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( | 295 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( |
296 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
282 uint8 endpoint, | 297 uint8 endpoint, |
283 scoped_refptr<net::IOBuffer> buffer, | 298 scoped_refptr<net::IOBuffer> buffer, |
284 int length, | 299 int length, |
285 unsigned int timeout, | 300 unsigned int timeout, |
301 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
286 const UsbTransferCallback& callback) { | 302 const UsbTransferCallback& callback) { |
287 scoped_ptr<Transfer> transfer( | 303 scoped_ptr<Transfer> transfer(new Transfer( |
288 new Transfer(USB_TRANSFER_INTERRUPT, buffer, length, callback)); | 304 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
305 USB_TRANSFER_INTERRUPT, buffer, length, task_runner, callback)); | |
289 | 306 |
290 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 307 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
291 if (!transfer->platform_transfer_) { | 308 if (!transfer->platform_transfer_) { |
292 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; | 309 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; |
293 return nullptr; | 310 return nullptr; |
294 } | 311 } |
295 | 312 |
296 libusb_fill_interrupt_transfer( | 313 libusb_fill_interrupt_transfer( |
297 transfer->platform_transfer_, nullptr, /* filled in by Submit() */ | 314 transfer->platform_transfer_, device_handle->handle_, endpoint, |
298 endpoint, reinterpret_cast<uint8*>(buffer->data()), | 315 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length), |
299 static_cast<int>(length), | |
300 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), | 316 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), |
301 timeout); | 317 timeout); |
302 | 318 |
303 return transfer.Pass(); | 319 return transfer.Pass(); |
304 } | 320 } |
305 | 321 |
306 // static | 322 // static |
307 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 323 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
308 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( | 324 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( |
325 scoped_refptr<UsbDeviceHandleImpl> device_handle, | |
309 uint8 endpoint, | 326 uint8 endpoint, |
310 scoped_refptr<net::IOBuffer> buffer, | 327 scoped_refptr<net::IOBuffer> buffer, |
311 size_t length, | 328 size_t length, |
312 unsigned int packets, | 329 unsigned int packets, |
313 unsigned int packet_length, | 330 unsigned int packet_length, |
314 unsigned int timeout, | 331 unsigned int timeout, |
332 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
315 const UsbTransferCallback& callback) { | 333 const UsbTransferCallback& callback) { |
316 DCHECK(packets <= length && (packets * packet_length) <= length) | 334 DCHECK(packets <= length && (packets * packet_length) <= length) |
317 << "transfer length is too small"; | 335 << "transfer length is too small"; |
318 | 336 |
319 scoped_ptr<Transfer> transfer( | 337 scoped_ptr<Transfer> transfer(new Transfer( |
320 new Transfer(USB_TRANSFER_ISOCHRONOUS, buffer, length, callback)); | 338 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
339 USB_TRANSFER_ISOCHRONOUS, buffer, length, task_runner, callback)); | |
321 | 340 |
322 transfer->platform_transfer_ = libusb_alloc_transfer(packets); | 341 transfer->platform_transfer_ = libusb_alloc_transfer(packets); |
323 if (!transfer->platform_transfer_) { | 342 if (!transfer->platform_transfer_) { |
324 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; | 343 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; |
325 return nullptr; | 344 return nullptr; |
326 } | 345 } |
327 | 346 |
328 libusb_fill_iso_transfer( | 347 libusb_fill_iso_transfer( |
329 transfer->platform_transfer_, nullptr, /* filled in by Submit() */ | 348 transfer->platform_transfer_, device_handle->handle_, endpoint, |
330 endpoint, reinterpret_cast<uint8*>(buffer->data()), | 349 reinterpret_cast<uint8*>(buffer->data()), static_cast<int>(length), |
331 static_cast<int>(length), packets, &Transfer::PlatformCallback, | 350 packets, &Transfer::PlatformCallback, transfer.get(), timeout); |
332 transfer.get(), timeout); | |
333 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length); | 351 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length); |
334 | 352 |
335 return transfer.Pass(); | 353 return transfer.Pass(); |
336 } | 354 } |
337 | 355 |
338 UsbDeviceHandleImpl::Transfer::Transfer(UsbTransferType transfer_type, | 356 UsbDeviceHandleImpl::Transfer::Transfer( |
339 scoped_refptr<net::IOBuffer> buffer, | 357 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
340 size_t length, | 358 scoped_refptr<InterfaceClaimer> claimed_interface, |
341 const UsbTransferCallback& callback) | 359 UsbTransferType transfer_type, |
360 scoped_refptr<net::IOBuffer> buffer, | |
361 size_t length, | |
362 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
363 const UsbTransferCallback& callback) | |
342 : transfer_type_(transfer_type), | 364 : transfer_type_(transfer_type), |
365 device_handle_(device_handle), | |
366 platform_transfer_(NULL), | |
343 buffer_(buffer), | 367 buffer_(buffer), |
368 claimed_interface_(claimed_interface), | |
344 length_(length), | 369 length_(length), |
345 cancelled_(false), | 370 cancelled_(false), |
371 task_runner_(task_runner), | |
346 callback_(callback) { | 372 callback_(callback) { |
347 // Remember the thread from which this transfer was created so that |callback| | |
348 // can be dispatched there. | |
349 callback_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
350 } | 373 } |
351 | 374 |
352 UsbDeviceHandleImpl::Transfer::~Transfer() { | 375 UsbDeviceHandleImpl::Transfer::~Transfer() { |
353 if (platform_transfer_) { | 376 if (platform_transfer_) { |
354 libusb_free_transfer(platform_transfer_); | 377 libusb_free_transfer(platform_transfer_); |
355 } | 378 } |
356 } | 379 } |
357 | 380 |
358 bool UsbDeviceHandleImpl::Transfer::Submit( | 381 void UsbDeviceHandleImpl::Transfer::Submit() { |
359 base::WeakPtr<UsbDeviceHandleImpl> device_handle) { | |
360 device_handle_ = device_handle; | |
361 // Remember the thread from which this transfer was submitted so that it can | |
362 // be marked complete there. | |
363 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
364 // GetClaimedInterfaceForEndpoint may return nullptr. libusb_submit_transfer | |
365 // will fail if it requires an interface we didn't claim. | |
366 claimed_interface_ = device_handle->GetClaimedInterfaceForEndpoint( | |
367 platform_transfer_->endpoint); | |
368 platform_transfer_->dev_handle = device_handle_->handle_; | |
369 | |
370 const int rv = libusb_submit_transfer(platform_transfer_); | 382 const int rv = libusb_submit_transfer(platform_transfer_); |
371 if (rv == LIBUSB_SUCCESS) { | 383 if (rv != LIBUSB_SUCCESS) { |
372 return true; | |
373 } else { | |
374 USB_LOG(EVENT) << "Failed to submit transfer: " | 384 USB_LOG(EVENT) << "Failed to submit transfer: " |
375 << ConvertPlatformUsbErrorToString(rv); | 385 << ConvertPlatformUsbErrorToString(rv); |
376 Complete(USB_TRANSFER_ERROR, 0); | 386 TransferComplete(USB_TRANSFER_ERROR, 0); |
377 return false; | |
378 } | 387 } |
379 } | 388 } |
380 | 389 |
381 void UsbDeviceHandleImpl::Transfer::Cancel() { | 390 void UsbDeviceHandleImpl::Transfer::Cancel() { |
382 if (!cancelled_) { | 391 if (!cancelled_) { |
383 libusb_cancel_transfer(platform_transfer_); | 392 libusb_cancel_transfer(platform_transfer_); |
384 claimed_interface_ = nullptr; | 393 claimed_interface_ = nullptr; |
385 } | 394 } |
386 cancelled_ = true; | 395 cancelled_ = true; |
387 } | 396 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
446 | 455 |
447 case USB_TRANSFER_BULK: | 456 case USB_TRANSFER_BULK: |
448 case USB_TRANSFER_INTERRUPT: | 457 case USB_TRANSFER_INTERRUPT: |
449 break; | 458 break; |
450 | 459 |
451 default: | 460 default: |
452 NOTREACHED() << "Invalid usb transfer type"; | 461 NOTREACHED() << "Invalid usb transfer type"; |
453 break; | 462 break; |
454 } | 463 } |
455 | 464 |
456 Complete(ConvertTransferStatus(platform_transfer_->status), actual_length); | 465 TransferComplete(ConvertTransferStatus(platform_transfer_->status), |
457 } | 466 actual_length); |
458 | |
459 void UsbDeviceHandleImpl::Transfer::Complete(UsbTransferStatus status, | |
460 size_t bytes_transferred) { | |
461 if (callback_task_runner_->RunsTasksOnCurrentThread()) { | |
462 callback_.Run(status, buffer_, bytes_transferred); | |
463 } else { | |
464 callback_task_runner_->PostTask( | |
465 FROM_HERE, base::Bind(callback_, status, buffer_, bytes_transferred)); | |
466 } | |
467 } | 467 } |
468 | 468 |
469 /* static */ | 469 /* static */ |
470 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( | 470 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( |
471 PlatformUsbTransferHandle platform_transfer) { | 471 PlatformUsbTransferHandle platform_transfer) { |
472 scoped_ptr<Transfer> transfer( | 472 Transfer* transfer = |
473 reinterpret_cast<Transfer*>(platform_transfer->user_data)); | 473 reinterpret_cast<Transfer*>(platform_transfer->user_data); |
474 DCHECK(transfer->platform_transfer_ == platform_transfer); | 474 DCHECK(transfer->platform_transfer_ == platform_transfer); |
475 | 475 transfer->ProcessCompletion(); |
476 // Because device_handle_ is a weak pointer it is guaranteed that the callback | |
477 // will be discarded if the handle has been freed. | |
478 Transfer* tmp_transfer = transfer.get(); // base::Passed invalidates transfer | |
479 tmp_transfer->task_runner_->PostTask( | |
480 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::CompleteTransfer, | |
481 tmp_transfer->device_handle_, | |
482 base::Passed(&transfer))); | |
483 } | 476 } |
484 | 477 |
485 UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, | 478 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, |
486 scoped_refptr<UsbDeviceImpl> device, | 479 size_t bytes_transferred) { |
487 PlatformUsbDeviceHandle handle) | 480 task_runner_->PostTask( |
481 FROM_HERE, | |
482 base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_, | |
483 base::Owned(this), | |
484 base::Bind(callback_, status, buffer_, bytes_transferred))); | |
485 } | |
486 | |
487 UsbDeviceHandleImpl::UsbDeviceHandleImpl( | |
488 scoped_refptr<UsbContext> context, | |
489 scoped_refptr<UsbDeviceImpl> device, | |
490 PlatformUsbDeviceHandle handle, | |
491 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | |
488 : device_(device), | 492 : device_(device), |
489 handle_(handle), | 493 handle_(handle), |
490 context_(context), | 494 context_(context), |
491 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 495 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
492 weak_factory_(this) { | 496 blocking_task_runner_(blocking_task_runner) { |
493 DCHECK(handle) << "Cannot create device with NULL handle."; | 497 DCHECK(handle) << "Cannot create device with NULL handle."; |
494 } | 498 } |
495 | 499 |
496 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { | 500 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { |
497 DCHECK(thread_checker_.CalledOnValidThread()); | 501 DCHECK(thread_checker_.CalledOnValidThread()); |
498 | 502 |
499 libusb_close(handle_); | 503 libusb_close(handle_); |
500 handle_ = NULL; | 504 handle_ = NULL; |
501 } | 505 } |
502 | 506 |
503 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { | 507 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { |
504 return device_; | 508 return device_; |
505 } | 509 } |
506 | 510 |
507 void UsbDeviceHandleImpl::Close() { | 511 void UsbDeviceHandleImpl::Close() { |
508 DCHECK(thread_checker_.CalledOnValidThread()); | 512 DCHECK(thread_checker_.CalledOnValidThread()); |
509 if (device_) | 513 if (device_) |
510 device_->Close(this); | 514 device_->Close(this); |
511 } | 515 } |
512 | 516 |
513 bool UsbDeviceHandleImpl::SetConfiguration(int configuration_value) { | 517 void UsbDeviceHandleImpl::SetConfiguration(int configuration_value, |
518 const UsbSuccessCallback& callback) { | |
514 DCHECK(thread_checker_.CalledOnValidThread()); | 519 DCHECK(thread_checker_.CalledOnValidThread()); |
515 if (!device_) { | 520 if (!device_) { |
516 return false; | 521 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
522 return; | |
517 } | 523 } |
518 | 524 |
519 for (Transfer* transfer : transfers_) { | 525 for (Transfer* transfer : transfers_) { |
520 transfer->Cancel(); | 526 transfer->Cancel(); |
521 } | 527 } |
522 claimed_interfaces_.clear(); | 528 claimed_interfaces_.clear(); |
523 | 529 |
524 int rv = libusb_set_configuration(handle_, configuration_value); | 530 blocking_task_runner_->PostTask( |
525 if (rv == LIBUSB_SUCCESS) { | 531 FROM_HERE, |
526 device_->RefreshConfiguration(); | 532 base::Bind(&UsbDeviceHandleImpl::SetConfigurationOnBlockingThread, this, |
527 RefreshEndpointMap(); | 533 handle_, configuration_value, callback)); |
528 } else { | |
529 USB_LOG(EVENT) << "Failed to set configuration " << configuration_value | |
530 << ": " << ConvertPlatformUsbErrorToString(rv); | |
531 } | |
532 return rv == LIBUSB_SUCCESS; | |
533 } | 534 } |
534 | 535 |
535 bool UsbDeviceHandleImpl::ClaimInterface(const int interface_number) { | 536 void UsbDeviceHandleImpl::ClaimInterface(int interface_number, |
537 const UsbSuccessCallback& callback) { | |
538 DCHECK(thread_checker_.CalledOnValidThread()); | |
539 if (!device_) { | |
540 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); | |
541 return; | |
542 } | |
543 if (ContainsKey(claimed_interfaces_, interface_number)) { | |
544 task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); | |
Ken Rockot(use gerrit already)
2015/04/07 22:09:43
nit: Maybe it doesn't matter, but is there realist
Reilly Grant (use Gerrit)
2015/04/08 21:39:03
I'll change it because I've recently decided that
| |
545 return; | |
546 } | |
547 | |
548 blocking_task_runner_->PostTask( | |
549 FROM_HERE, | |
550 base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread, this, | |
551 handle_, interface_number, callback)); | |
552 } | |
553 | |
554 bool UsbDeviceHandleImpl::ReleaseInterface(int interface_number) { | |
536 DCHECK(thread_checker_.CalledOnValidThread()); | 555 DCHECK(thread_checker_.CalledOnValidThread()); |
537 if (!device_) | 556 if (!device_) |
538 return false; | 557 return false; |
539 if (ContainsKey(claimed_interfaces_, interface_number)) | |
540 return true; | |
541 | |
542 scoped_refptr<InterfaceClaimer> claimer = | |
543 new InterfaceClaimer(this, interface_number); | |
544 | |
545 if (claimer->Claim()) { | |
546 claimed_interfaces_[interface_number] = claimer; | |
547 RefreshEndpointMap(); | |
548 return true; | |
549 } | |
550 return false; | |
551 } | |
552 | |
553 bool UsbDeviceHandleImpl::ReleaseInterface(const int interface_number) { | |
554 DCHECK(thread_checker_.CalledOnValidThread()); | |
555 if (!device_) | |
556 return false; | |
557 if (!ContainsKey(claimed_interfaces_, interface_number)) | 558 if (!ContainsKey(claimed_interfaces_, interface_number)) |
558 return false; | 559 return false; |
559 | 560 |
560 // Cancel all the transfers on that interface. | 561 // Cancel all the transfers on that interface. |
561 InterfaceClaimer* interface_claimer = | 562 InterfaceClaimer* interface_claimer = |
562 claimed_interfaces_[interface_number].get(); | 563 claimed_interfaces_[interface_number].get(); |
563 for (Transfer* transfer : transfers_) { | 564 for (Transfer* transfer : transfers_) { |
564 if (transfer->claimed_interface() == interface_claimer) { | 565 if (transfer->claimed_interface() == interface_claimer) { |
565 transfer->Cancel(); | 566 transfer->Cancel(); |
566 } | 567 } |
567 } | 568 } |
568 claimed_interfaces_.erase(interface_number); | 569 claimed_interfaces_.erase(interface_number); |
569 | 570 |
570 RefreshEndpointMap(); | 571 RefreshEndpointMap(); |
571 return true; | 572 return true; |
572 } | 573 } |
573 | 574 |
574 bool UsbDeviceHandleImpl::SetInterfaceAlternateSetting( | 575 void UsbDeviceHandleImpl::SetInterfaceAlternateSetting( |
575 const int interface_number, | 576 int interface_number, |
576 const int alternate_setting) { | 577 int alternate_setting, |
578 const UsbSuccessCallback& callback) { | |
577 DCHECK(thread_checker_.CalledOnValidThread()); | 579 DCHECK(thread_checker_.CalledOnValidThread()); |
578 if (!device_) | 580 if (!device_ || !ContainsKey(claimed_interfaces_, interface_number)) { |
579 return false; | 581 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
580 if (!ContainsKey(claimed_interfaces_, interface_number)) | 582 return; |
581 return false; | |
582 const int rv = libusb_set_interface_alt_setting( | |
583 handle_, interface_number, alternate_setting); | |
584 if (rv == LIBUSB_SUCCESS) { | |
585 claimed_interfaces_[interface_number]->set_alternate_setting( | |
586 alternate_setting); | |
587 RefreshEndpointMap(); | |
588 } else { | |
589 USB_LOG(EVENT) << "Failed to set interface " << interface_number | |
590 << " to alternate setting " << alternate_setting << ": " | |
591 << ConvertPlatformUsbErrorToString(rv); | |
592 } | 583 } |
593 return rv == LIBUSB_SUCCESS; | 584 |
585 blocking_task_runner_->PostTask( | |
586 FROM_HERE, | |
587 base::Bind( | |
588 &UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread, | |
589 this, handle_, interface_number, alternate_setting, callback)); | |
594 } | 590 } |
595 | 591 |
596 bool UsbDeviceHandleImpl::ResetDevice() { | 592 void UsbDeviceHandleImpl::ResetDevice(const UsbSuccessCallback& callback) { |
597 DCHECK(thread_checker_.CalledOnValidThread()); | 593 DCHECK(thread_checker_.CalledOnValidThread()); |
598 if (!device_) | 594 if (!device_) { |
599 return false; | 595 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); |
600 | 596 return; |
601 const int rv = libusb_reset_device(handle_); | |
602 if (rv != LIBUSB_SUCCESS) { | |
603 USB_LOG(EVENT) << "Failed to reset device: " | |
604 << ConvertPlatformUsbErrorToString(rv); | |
605 } | |
606 return rv == LIBUSB_SUCCESS; | |
607 } | |
608 | |
609 bool UsbDeviceHandleImpl::GetStringDescriptor(uint8 string_id, | |
610 base::string16* string) { | |
611 if (!GetSupportedLanguages()) { | |
612 return false; | |
613 } | 597 } |
614 | 598 |
615 std::map<uint8, base::string16>::const_iterator it = strings_.find(string_id); | 599 blocking_task_runner_->PostTask( |
616 if (it != strings_.end()) { | 600 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceOnBlockingThread, |
617 *string = it->second; | 601 this, handle_, callback)); |
618 return true; | |
619 } | |
620 | |
621 for (size_t i = 0; i < languages_.size(); ++i) { | |
622 // Get the string using language ID. | |
623 uint16 language_id = languages_[i]; | |
624 // The 1-byte length field limits the descriptor to 256-bytes (128 char16s). | |
625 base::char16 text[128]; | |
626 int size = | |
627 libusb_get_string_descriptor(handle_, | |
628 string_id, | |
629 language_id, | |
630 reinterpret_cast<unsigned char*>(&text[0]), | |
631 sizeof(text)); | |
632 if (size < 0) { | |
633 USB_LOG(EVENT) << "Failed to get string descriptor " << string_id | |
634 << " (langid " << language_id | |
635 << "): " << ConvertPlatformUsbErrorToString(size); | |
636 continue; | |
637 } else if (size < 2) { | |
638 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid " | |
639 << language_id << ") has no header."; | |
640 continue; | |
641 // The first 2 bytes of the descriptor are the total length and type tag. | |
642 } else if ((text[0] & 0xff) != size) { | |
643 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid " | |
644 << language_id << ") size mismatch: " << (text[0] & 0xff) | |
645 << " != " << size; | |
646 continue; | |
647 } else if ((text[0] >> 8) != LIBUSB_DT_STRING) { | |
648 USB_LOG(EVENT) << "String descriptor " << string_id << " (langid " | |
649 << language_id << ") is not a string descriptor."; | |
650 continue; | |
651 } | |
652 | |
653 *string = base::string16(text + 1, (size - 2) / 2); | |
654 strings_[string_id] = *string; | |
655 return true; | |
656 } | |
657 | |
658 return false; | |
659 } | 602 } |
660 | 603 |
661 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction, | 604 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction, |
662 TransferRequestType request_type, | 605 TransferRequestType request_type, |
663 TransferRecipient recipient, | 606 TransferRecipient recipient, |
664 uint8 request, | 607 uint8 request, |
665 uint16 value, | 608 uint16 value, |
666 uint16 index, | 609 uint16 index, |
667 net::IOBuffer* buffer, | 610 net::IOBuffer* buffer, |
668 size_t length, | 611 size_t length, |
669 unsigned int timeout, | 612 unsigned int timeout, |
670 const UsbTransferCallback& callback) { | 613 const UsbTransferCallback& callback) { |
614 DCHECK(thread_checker_.CalledOnValidThread()); | |
615 | |
616 if (!device_) { | |
617 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); | |
618 return; | |
619 } | |
620 | |
671 if (length > UINT16_MAX) { | 621 if (length > UINT16_MAX) { |
672 USB_LOG(USER) << "Transfer too long."; | 622 USB_LOG(USER) << "Transfer too long."; |
673 callback.Run(USB_TRANSFER_ERROR, buffer, 0); | 623 callback.Run(USB_TRANSFER_ERROR, buffer, 0); |
674 return; | 624 return; |
675 } | 625 } |
676 | 626 |
677 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; | 627 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; |
678 scoped_refptr<net::IOBuffer> resized_buffer( | 628 scoped_refptr<net::IOBuffer> resized_buffer( |
679 new net::IOBufferWithSize(static_cast<int>(resized_length))); | 629 new net::IOBufferWithSize(static_cast<int>(resized_length))); |
680 if (!resized_buffer.get()) { | 630 if (!resized_buffer.get()) { |
681 callback.Run(USB_TRANSFER_ERROR, buffer, 0); | 631 callback.Run(USB_TRANSFER_ERROR, buffer, 0); |
682 return; | 632 return; |
683 } | 633 } |
684 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), | 634 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), |
685 length); | 635 length); |
686 | 636 |
687 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer( | 637 scoped_ptr<Transfer> transfer = Transfer::CreateControlTransfer( |
688 CreateRequestType(direction, request_type, recipient), request, value, | 638 this, CreateRequestType(direction, request_type, recipient), request, |
689 index, static_cast<uint16>(length), resized_buffer, timeout, callback); | 639 value, index, static_cast<uint16>(length), resized_buffer, timeout, |
640 task_runner_, callback); | |
690 if (!transfer) { | 641 if (!transfer) { |
691 callback.Run(USB_TRANSFER_ERROR, buffer, 0); | 642 callback.Run(USB_TRANSFER_ERROR, buffer, 0); |
692 return; | 643 return; |
693 } | 644 } |
694 | 645 |
695 PostOrSubmitTransfer(transfer.Pass()); | 646 SubmitTransfer(transfer.Pass()); |
696 } | 647 } |
697 | 648 |
698 void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction, | 649 void UsbDeviceHandleImpl::BulkTransfer(const UsbEndpointDirection direction, |
699 const uint8 endpoint, | 650 const uint8 endpoint, |
700 net::IOBuffer* buffer, | 651 net::IOBuffer* buffer, |
701 const size_t length, | 652 const size_t length, |
702 const unsigned int timeout, | 653 const unsigned int timeout, |
703 const UsbTransferCallback& callback) { | 654 const UsbTransferCallback& callback) { |
655 DCHECK(thread_checker_.CalledOnValidThread()); | |
656 | |
657 if (!device_) { | |
658 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); | |
659 return; | |
660 } | |
661 | |
704 if (length > INT_MAX) { | 662 if (length > INT_MAX) { |
705 USB_LOG(USER) << "Transfer too long."; | 663 USB_LOG(USER) << "Transfer too long."; |
706 callback.Run(USB_TRANSFER_ERROR, buffer, 0); | 664 callback.Run(USB_TRANSFER_ERROR, buffer, 0); |
707 return; | 665 return; |
708 } | 666 } |
709 | 667 |
710 scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer( | 668 scoped_ptr<Transfer> transfer = Transfer::CreateBulkTransfer( |
711 ConvertTransferDirection(direction) | endpoint, buffer, | 669 this, ConvertTransferDirection(direction) | endpoint, buffer, |
712 static_cast<int>(length), timeout, callback); | 670 static_cast<int>(length), timeout, task_runner_, callback); |
713 | 671 |
714 PostOrSubmitTransfer(transfer.Pass()); | 672 SubmitTransfer(transfer.Pass()); |
715 } | 673 } |
716 | 674 |
717 void UsbDeviceHandleImpl::InterruptTransfer( | 675 void UsbDeviceHandleImpl::InterruptTransfer( |
718 UsbEndpointDirection direction, | 676 UsbEndpointDirection direction, |
719 uint8 endpoint, | 677 uint8 endpoint, |
720 net::IOBuffer* buffer, | 678 net::IOBuffer* buffer, |
721 size_t length, | 679 size_t length, |
722 unsigned int timeout, | 680 unsigned int timeout, |
723 const UsbTransferCallback& callback) { | 681 const UsbTransferCallback& callback) { |
682 DCHECK(thread_checker_.CalledOnValidThread()); | |
683 | |
684 if (!device_) { | |
685 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); | |
686 return; | |
687 } | |
688 | |
724 if (length > INT_MAX) { | 689 if (length > INT_MAX) { |
725 USB_LOG(USER) << "Transfer too long."; | 690 USB_LOG(USER) << "Transfer too long."; |
726 callback.Run(USB_TRANSFER_ERROR, buffer, 0); | 691 callback.Run(USB_TRANSFER_ERROR, buffer, 0); |
727 return; | 692 return; |
728 } | 693 } |
729 | 694 |
730 scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer( | 695 scoped_ptr<Transfer> transfer = Transfer::CreateInterruptTransfer( |
731 ConvertTransferDirection(direction) | endpoint, buffer, | 696 this, ConvertTransferDirection(direction) | endpoint, buffer, |
732 static_cast<int>(length), timeout, callback); | 697 static_cast<int>(length), timeout, task_runner_, callback); |
733 | 698 |
734 PostOrSubmitTransfer(transfer.Pass()); | 699 SubmitTransfer(transfer.Pass()); |
735 } | 700 } |
736 | 701 |
737 void UsbDeviceHandleImpl::IsochronousTransfer( | 702 void UsbDeviceHandleImpl::IsochronousTransfer( |
738 const UsbEndpointDirection direction, | 703 const UsbEndpointDirection direction, |
739 const uint8 endpoint, | 704 const uint8 endpoint, |
740 net::IOBuffer* buffer, | 705 net::IOBuffer* buffer, |
741 const size_t length, | 706 const size_t length, |
742 const unsigned int packets, | 707 const unsigned int packets, |
743 const unsigned int packet_length, | 708 const unsigned int packet_length, |
744 const unsigned int timeout, | 709 const unsigned int timeout, |
745 const UsbTransferCallback& callback) { | 710 const UsbTransferCallback& callback) { |
711 DCHECK(thread_checker_.CalledOnValidThread()); | |
712 | |
713 if (!device_) { | |
714 callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0); | |
715 return; | |
716 } | |
717 | |
746 if (length > INT_MAX) { | 718 if (length > INT_MAX) { |
747 USB_LOG(USER) << "Transfer too long."; | 719 USB_LOG(USER) << "Transfer too long."; |
748 callback.Run(USB_TRANSFER_ERROR, buffer, 0); | 720 callback.Run(USB_TRANSFER_ERROR, buffer, 0); |
749 return; | 721 return; |
750 } | 722 } |
751 | 723 |
752 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 724 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
753 ConvertTransferDirection(direction) | endpoint, buffer, | 725 this, ConvertTransferDirection(direction) | endpoint, buffer, |
754 static_cast<int>(length), packets, packet_length, timeout, callback); | 726 static_cast<int>(length), packets, packet_length, timeout, task_runner_, |
727 callback); | |
755 | 728 |
756 PostOrSubmitTransfer(transfer.Pass()); | 729 SubmitTransfer(transfer.Pass()); |
730 } | |
731 | |
732 void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread( | |
733 PlatformUsbDeviceHandle handle, | |
734 int configuration_value, | |
735 const UsbSuccessCallback& callback) { | |
736 int rv = libusb_set_configuration(handle_, configuration_value); | |
737 if (rv != LIBUSB_SUCCESS) { | |
738 USB_LOG(EVENT) << "Failed to set configuration " << configuration_value | |
739 << ": " << ConvertPlatformUsbErrorToString(rv); | |
740 } | |
741 task_runner_->PostTask( | |
742 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SetConfigurationComplete, | |
743 this, rv == LIBUSB_SUCCESS, callback)); | |
744 } | |
745 | |
746 void UsbDeviceHandleImpl::SetConfigurationComplete( | |
747 bool success, | |
748 const UsbSuccessCallback& callback) { | |
749 if (success) { | |
750 device_->RefreshConfiguration(); | |
751 RefreshEndpointMap(); | |
752 } | |
753 callback.Run(success); | |
754 } | |
755 | |
756 void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread( | |
757 PlatformUsbDeviceHandle handle, | |
758 int interface_number, | |
759 const UsbSuccessCallback& callback) { | |
760 int rv = libusb_claim_interface(handle, interface_number); | |
761 if (rv != LIBUSB_SUCCESS) { | |
762 VLOG(1) << "Failed to claim interface: " | |
763 << ConvertPlatformUsbErrorToString(rv); | |
764 } | |
765 task_runner_->PostTask( | |
766 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ClaimInterfaceComplete, this, | |
767 interface_number, rv == LIBUSB_SUCCESS, callback)); | |
768 } | |
769 | |
770 void UsbDeviceHandleImpl::ClaimInterfaceComplete( | |
771 int interface_number, | |
772 bool success, | |
773 const UsbSuccessCallback& callback) { | |
774 if (success) { | |
775 claimed_interfaces_[interface_number] = | |
776 new InterfaceClaimer(this, interface_number); | |
777 RefreshEndpointMap(); | |
778 } | |
779 callback.Run(success); | |
780 } | |
781 | |
782 void UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread( | |
783 PlatformUsbDeviceHandle handle, | |
784 int interface_number, | |
785 int alternate_setting, | |
786 const UsbSuccessCallback& callback) { | |
787 int rv = libusb_set_interface_alt_setting(handle, interface_number, | |
788 alternate_setting); | |
789 if (rv != LIBUSB_SUCCESS) { | |
790 USB_LOG(EVENT) << "Failed to set interface " << interface_number | |
791 << " to alternate setting " << alternate_setting << ": " | |
792 << ConvertPlatformUsbErrorToString(rv); | |
793 } | |
794 task_runner_->PostTask( | |
795 FROM_HERE, | |
796 base::Bind(&UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete, | |
797 this, interface_number, alternate_setting, | |
798 rv == LIBUSB_SUCCESS, callback)); | |
799 } | |
800 | |
801 void UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete( | |
802 int interface_number, | |
803 int alternate_setting, | |
804 bool success, | |
805 const UsbSuccessCallback& callback) { | |
806 if (success) { | |
807 claimed_interfaces_[interface_number]->set_alternate_setting( | |
808 alternate_setting); | |
809 RefreshEndpointMap(); | |
810 } | |
811 callback.Run(success); | |
812 } | |
813 | |
814 void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread( | |
815 PlatformUsbDeviceHandle handle, | |
816 const UsbSuccessCallback& callback) { | |
817 int rv = libusb_reset_device(handle); | |
818 if (rv != LIBUSB_SUCCESS) { | |
819 USB_LOG(EVENT) << "Failed to reset device: " | |
820 << ConvertPlatformUsbErrorToString(rv); | |
821 } | |
822 task_runner_->PostTask( | |
823 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ResetDeviceComplete, this, | |
824 rv == LIBUSB_SUCCESS, callback)); | |
825 } | |
826 | |
827 void UsbDeviceHandleImpl::ResetDeviceComplete( | |
828 bool success, | |
829 const UsbSuccessCallback& callback) { | |
830 callback.Run(success); | |
757 } | 831 } |
758 | 832 |
759 void UsbDeviceHandleImpl::RefreshEndpointMap() { | 833 void UsbDeviceHandleImpl::RefreshEndpointMap() { |
760 DCHECK(thread_checker_.CalledOnValidThread()); | 834 DCHECK(thread_checker_.CalledOnValidThread()); |
761 endpoint_map_.clear(); | 835 endpoint_map_.clear(); |
762 const UsbConfigDescriptor* config = device_->GetConfiguration(); | 836 const UsbConfigDescriptor* config = device_->GetConfiguration(); |
763 if (config) { | 837 if (config) { |
764 for (const auto& map_entry : claimed_interfaces_) { | 838 for (const auto& map_entry : claimed_interfaces_) { |
765 int interface_number = map_entry.first; | 839 int interface_number = map_entry.first; |
766 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second; | 840 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second; |
(...skipping 11 matching lines...) Expand all Loading... | |
778 } | 852 } |
779 } | 853 } |
780 | 854 |
781 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> | 855 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> |
782 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { | 856 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { |
783 if (ContainsKey(endpoint_map_, endpoint)) | 857 if (ContainsKey(endpoint_map_, endpoint)) |
784 return claimed_interfaces_[endpoint_map_[endpoint]]; | 858 return claimed_interfaces_[endpoint_map_[endpoint]]; |
785 return NULL; | 859 return NULL; |
786 } | 860 } |
787 | 861 |
788 void UsbDeviceHandleImpl::PostOrSubmitTransfer(scoped_ptr<Transfer> transfer) { | |
789 if (task_runner_->RunsTasksOnCurrentThread()) { | |
790 SubmitTransfer(transfer.Pass()); | |
791 } else { | |
792 task_runner_->PostTask( | |
793 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::SubmitTransfer, this, | |
794 base::Passed(&transfer))); | |
795 } | |
796 } | |
797 | |
798 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) { | 862 void UsbDeviceHandleImpl::SubmitTransfer(scoped_ptr<Transfer> transfer) { |
799 DCHECK(thread_checker_.CalledOnValidThread()); | 863 DCHECK(thread_checker_.CalledOnValidThread()); |
800 | 864 |
801 if (device_) { | 865 // Transfer is owned by libusb until its completion callback is run. This |
802 if (transfer->Submit(weak_factory_.GetWeakPtr())) { | 866 // object holds a weak reference. |
803 // Transfer is now owned by libusb until its completion callback is run. | 867 transfers_.insert(transfer.get()); |
804 // This object holds a weak reference. | 868 blocking_task_runner_->PostTask( |
805 transfers_.insert(transfer.release()); | 869 FROM_HERE, |
806 } | 870 base::Bind(&Transfer::Submit, base::Unretained(transfer.release()))); |
807 } else { | |
808 transfer->Complete(USB_TRANSFER_DISCONNECT, 0); | |
809 } | |
810 } | 871 } |
811 | 872 |
812 void UsbDeviceHandleImpl::CompleteTransfer(scoped_ptr<Transfer> transfer) { | 873 void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer, |
813 DCHECK(ContainsKey(transfers_, transfer.get())) | 874 const base::Closure& callback) { |
814 << "Missing transfer completed"; | 875 DCHECK(thread_checker_.CalledOnValidThread()); |
815 transfers_.erase(transfer.get()); | 876 DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed"; |
816 transfer->ProcessCompletion(); | 877 transfers_.erase(transfer); |
817 } | 878 callback.Run(); |
818 | |
819 bool UsbDeviceHandleImpl::GetSupportedLanguages() { | |
820 if (!languages_.empty()) { | |
821 return true; | |
822 } | |
823 | |
824 // The 1-byte length field limits the descriptor to 256-bytes (128 uint16s). | |
825 uint16 languages[128]; | |
826 int size = libusb_get_string_descriptor( | |
827 handle_, | |
828 0, | |
829 0, | |
830 reinterpret_cast<unsigned char*>(&languages[0]), | |
831 sizeof(languages)); | |
832 if (size < 0) { | |
833 USB_LOG(EVENT) << "Failed to get list of supported languages: " | |
834 << ConvertPlatformUsbErrorToString(size); | |
835 return false; | |
836 } else if (size < 2) { | |
837 USB_LOG(EVENT) << "String descriptor zero has no header."; | |
838 return false; | |
839 // The first 2 bytes of the descriptor are the total length and type tag. | |
840 } else if ((languages[0] & 0xff) != size) { | |
841 USB_LOG(EVENT) << "String descriptor zero size mismatch: " | |
842 << (languages[0] & 0xff) << " != " << size; | |
843 return false; | |
844 } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) { | |
845 USB_LOG(EVENT) << "String descriptor zero is not a string descriptor."; | |
846 return false; | |
847 } | |
848 | |
849 languages_.assign(languages[1], languages[(size - 2) / 2]); | |
850 return true; | |
851 } | 879 } |
852 | 880 |
853 void UsbDeviceHandleImpl::InternalClose() { | 881 void UsbDeviceHandleImpl::InternalClose() { |
854 DCHECK(thread_checker_.CalledOnValidThread()); | 882 DCHECK(thread_checker_.CalledOnValidThread()); |
855 if (!device_) | 883 if (!device_) |
856 return; | 884 return; |
857 | 885 |
858 // Cancel all the transfers. | 886 // Cancel all the transfers. |
859 for (Transfer* transfer : transfers_) { | 887 for (Transfer* transfer : transfers_) { |
860 // The callback will be called some time later. | 888 // The callback will be called some time later. |
861 transfer->Cancel(); | 889 transfer->Cancel(); |
862 } | 890 } |
863 | 891 |
864 // Attempt-release all the interfaces. | 892 // Attempt-release all the interfaces. |
865 // It will be retained until the transfer cancellation is finished. | 893 // It will be retained until the transfer cancellation is finished. |
866 claimed_interfaces_.clear(); | 894 claimed_interfaces_.clear(); |
867 | 895 |
868 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to | 896 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to |
869 // finish. | 897 // finish. |
870 device_ = NULL; | 898 device_ = NULL; |
871 } | 899 } |
872 | 900 |
873 } // namespace device | 901 } // namespace device |
OLD | NEW |