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

Side by Side Diff: chrome/browser/usb/usb_device.cc

Issue 12471013: Add chrome.usb.listInterfaces API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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
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/usb/usb_device.h" 5 #include "chrome/browser/usb/usb_device.h"
6 6
7 #include <vector>
8
7 #include "base/stl_util.h" 9 #include "base/stl_util.h"
8 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "chrome/browser/usb/usb_interface.h"
9 #include "chrome/browser/usb/usb_service.h" 12 #include "chrome/browser/usb/usb_service.h"
10 #include "third_party/libusb/src/libusb/libusb.h" 13 #include "third_party/libusb/src/libusb/libusb.h"
11 14
12 namespace { 15 namespace {
13 16
14 static uint8 ConvertTransferDirection( 17 static uint8 ConvertTransferDirection(
15 const UsbDevice::TransferDirection direction) { 18 const UsbInterfaceDirection direction) {
16 switch (direction) { 19 switch (direction) {
17 case UsbDevice::INBOUND: 20 case USB_DIRECTION_INBOUND:
18 return LIBUSB_ENDPOINT_IN; 21 return LIBUSB_ENDPOINT_IN;
19 case UsbDevice::OUTBOUND: 22 case USB_DIRECTION_OUTBOUND:
20 return LIBUSB_ENDPOINT_OUT; 23 return LIBUSB_ENDPOINT_OUT;
21 } 24 }
22 NOTREACHED(); 25 NOTREACHED();
23 return LIBUSB_ENDPOINT_OUT; 26 return LIBUSB_ENDPOINT_OUT;
24 } 27 }
25 28
26 static uint8 CreateRequestType(const UsbDevice::TransferDirection direction, 29 static uint8 CreateRequestType(const UsbInterfaceDirection direction,
27 const UsbDevice::TransferRequestType request_type, 30 const UsbDevice::TransferRequestType request_type,
28 const UsbDevice::TransferRecipient recipient) { 31 const UsbDevice::TransferRecipient recipient) {
29 uint8 result = ConvertTransferDirection(direction); 32 uint8 result = ConvertTransferDirection(direction);
30 33
31 switch (request_type) { 34 switch (request_type) {
32 case UsbDevice::STANDARD: 35 case UsbDevice::STANDARD:
33 result |= LIBUSB_REQUEST_TYPE_STANDARD; 36 result |= LIBUSB_REQUEST_TYPE_STANDARD;
34 break; 37 break;
35 case UsbDevice::CLASS: 38 case UsbDevice::CLASS:
36 result |= LIBUSB_REQUEST_TYPE_CLASS; 39 result |= LIBUSB_REQUEST_TYPE_CLASS;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 123
121 DCHECK(handle->actual_length >= 0) << "Negative actual length received"; 124 DCHECK(handle->actual_length >= 0) << "Negative actual length received";
122 size_t actual_length = 125 size_t actual_length =
123 static_cast<size_t>(std::max(handle->actual_length, 0)); 126 static_cast<size_t>(std::max(handle->actual_length, 0));
124 127
125 DCHECK(transfer->length >= actual_length) << 128 DCHECK(transfer->length >= actual_length) <<
126 "data too big for our buffer (libusb failure?)"; 129 "data too big for our buffer (libusb failure?)";
127 130
128 scoped_refptr<net::IOBuffer> buffer = transfer->buffer; 131 scoped_refptr<net::IOBuffer> buffer = transfer->buffer;
129 switch (transfer->transfer_type) { 132 switch (transfer->transfer_type) {
130 case USB_TRANSFER_CONTROL: 133 case USB_ENDPOINT_CONTROL:
131 // If the transfer is a control transfer we do not expose the control 134 // If the transfer is a control transfer we do not expose the control
132 // setup header to the caller. This logic strips off the header if 135 // setup header to the caller. This logic strips off the header if
133 // present before invoking the callback provided with the transfer. 136 // present before invoking the callback provided with the transfer.
134 if (actual_length > 0) { 137 if (actual_length > 0) {
135 CHECK(transfer->length >= LIBUSB_CONTROL_SETUP_SIZE) << 138 CHECK(transfer->length >= LIBUSB_CONTROL_SETUP_SIZE) <<
136 "buffer was not correctly set: too small for the control header"; 139 "buffer was not correctly set: too small for the control header";
137 140
138 if (transfer->length >= actual_length && 141 if (transfer->length >= actual_length &&
139 actual_length >= LIBUSB_CONTROL_SETUP_SIZE) { 142 actual_length >= LIBUSB_CONTROL_SETUP_SIZE) {
140 // If the payload is zero bytes long, pad out the allocated buffer 143 // If the payload is zero bytes long, pad out the allocated buffer
141 // size to one byte so that an IOBuffer of that size can be allocated. 144 // size to one byte so that an IOBuffer of that size can be allocated.
142 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( 145 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer(
143 std::max(actual_length, static_cast<size_t>(1))); 146 std::max(actual_length, static_cast<size_t>(1)));
144 memcpy(resized_buffer->data(), 147 memcpy(resized_buffer->data(),
145 buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, 148 buffer->data() + LIBUSB_CONTROL_SETUP_SIZE,
146 actual_length); 149 actual_length);
147 buffer = resized_buffer; 150 buffer = resized_buffer;
148 } 151 }
149 } 152 }
150 break; 153 break;
151 154
152 case USB_TRANSFER_ISOCHRONOUS: 155 case USB_ENDPOINT_ISOCHRONOUS:
153 // Isochronous replies might carry data in the different isoc packets even 156 // Isochronous replies might carry data in the different isoc packets even
154 // if the transfer actual_data value is zero. Furthermore, not all of the 157 // if the transfer actual_data value is zero. Furthermore, not all of the
155 // received packets might contain data, so we need to calculate how many 158 // received packets might contain data, so we need to calculate how many
156 // data bytes we are effectively providing and pack the results. 159 // data bytes we are effectively providing and pack the results.
157 if (actual_length == 0) { 160 if (actual_length == 0) {
158 size_t packet_buffer_start = 0; 161 size_t packet_buffer_start = 0;
159 for (int i = 0; i < handle->num_iso_packets; ++i) { 162 for (int i = 0; i < handle->num_iso_packets; ++i) {
160 PlatformUsbIsoPacketDescriptor packet = &handle->iso_packet_desc[i]; 163 PlatformUsbIsoPacketDescriptor packet = &handle->iso_packet_desc[i];
161 if (packet->actual_length > 0) { 164 if (packet->actual_length > 0) {
162 // We don't need to copy as long as all packets until now provide 165 // We don't need to copy as long as all packets until now provide
163 // all the data the packet can hold. 166 // all the data the packet can hold.
164 if (actual_length < packet_buffer_start) { 167 if (actual_length < packet_buffer_start) {
165 CHECK(packet_buffer_start + packet->actual_length <= 168 CHECK(packet_buffer_start + packet->actual_length <=
166 transfer->length); 169 transfer->length);
167 memmove(buffer->data() + actual_length, 170 memmove(buffer->data() + actual_length,
168 buffer->data() + packet_buffer_start, 171 buffer->data() + packet_buffer_start,
169 packet->actual_length); 172 packet->actual_length);
170 } 173 }
171 actual_length += packet->actual_length; 174 actual_length += packet->actual_length;
172 } 175 }
173 176
174 packet_buffer_start += packet->length; 177 packet_buffer_start += packet->length;
175 } 178 }
176 } 179 }
177 break; 180 break;
178 181
179 case USB_TRANSFER_BULK: 182 case USB_ENDPOINT_BULK:
180 case USB_TRANSFER_INTERRUPT: 183 case USB_ENDPOINT_INTERRUPT:
181 break; 184 break;
182 185
183 default: 186 default:
184 NOTREACHED() << "Invalid usb transfer type"; 187 NOTREACHED() << "Invalid usb transfer type";
185 } 188 }
186 189
187 transfer->callback.Run(ConvertTransferStatus(handle->status), buffer, 190 transfer->callback.Run(ConvertTransferStatus(handle->status), buffer,
188 actual_length); 191 actual_length);
189 192
190 transfers_.erase(handle); 193 transfers_.erase(handle);
191 libusb_free_transfer(handle); 194 libusb_free_transfer(handle);
192 } 195 }
193 196
197 void UsbDevice::ListInterfaces(PlatformUsbConfigDescriptor* config,
198 const UsbInterfaceCallback& callback) {
199 PlatformUsbDevice device = libusb_get_device(handle_);
200
201 const int list_result = libusb_get_active_config_descriptor(device, config);
202 callback.Run(list_result == 0);
203 }
204
194 void UsbDevice::ClaimInterface(const int interface_number, 205 void UsbDevice::ClaimInterface(const int interface_number,
195 const UsbInterfaceCallback& callback) { 206 const UsbInterfaceCallback& callback) {
196 CheckDevice(); 207 CheckDevice();
197 208
198 const int claim_result = libusb_claim_interface(handle_, interface_number); 209 const int claim_result = libusb_claim_interface(handle_, interface_number);
199 callback.Run(claim_result == 0); 210 callback.Run(claim_result == 0);
200 } 211 }
201 212
202 void UsbDevice::ReleaseInterface(const int interface_number, 213 void UsbDevice::ReleaseInterface(const int interface_number,
203 const UsbInterfaceCallback& callback) { 214 const UsbInterfaceCallback& callback) {
204 CheckDevice(); 215 CheckDevice();
205 216
206 const int release_result = libusb_release_interface(handle_, 217 const int release_result = libusb_release_interface(handle_,
207 interface_number); 218 interface_number);
208 callback.Run(release_result == 0); 219 callback.Run(release_result == 0);
209 } 220 }
210 221
211 void UsbDevice::SetInterfaceAlternateSetting( 222 void UsbDevice::SetInterfaceAlternateSetting(
212 const int interface_number, 223 const int interface_number,
213 const int alternate_setting, 224 const int alternate_setting,
214 const UsbInterfaceCallback& callback) { 225 const UsbInterfaceCallback& callback) {
215 CheckDevice(); 226 CheckDevice();
216 227
217 const int setting_result = libusb_set_interface_alt_setting(handle_, 228 const int setting_result = libusb_set_interface_alt_setting(handle_,
218 interface_number, alternate_setting); 229 interface_number, alternate_setting);
219 230
220 callback.Run(setting_result == 0); 231 callback.Run(setting_result == 0);
221 } 232 }
222 233
223 void UsbDevice::ControlTransfer(const TransferDirection direction, 234 void UsbDevice::ControlTransfer(const UsbInterfaceDirection direction,
224 const TransferRequestType request_type, const TransferRecipient recipient, 235 const TransferRequestType request_type, const TransferRecipient recipient,
225 const uint8 request, const uint16 value, const uint16 index, 236 const uint8 request, const uint16 value, const uint16 index,
226 net::IOBuffer* buffer, const size_t length, const unsigned int timeout, 237 net::IOBuffer* buffer, const size_t length, const unsigned int timeout,
227 const UsbTransferCallback& callback) { 238 const UsbTransferCallback& callback) {
228 CheckDevice(); 239 CheckDevice();
229 240
230 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; 241 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length;
231 scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize( 242 scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize(
232 resized_length)); 243 resized_length));
233 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), 244 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(),
234 length); 245 length);
235 246
236 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); 247 struct libusb_transfer* const transfer = libusb_alloc_transfer(0);
237 const uint8 converted_type = CreateRequestType(direction, request_type, 248 const uint8 converted_type = CreateRequestType(direction, request_type,
238 recipient); 249 recipient);
239 libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()), 250 libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()),
240 converted_type, request, value, index, length); 251 converted_type, request, value, index, length);
241 libusb_fill_control_transfer(transfer, handle_, reinterpret_cast<uint8*>( 252 libusb_fill_control_transfer(transfer, handle_, reinterpret_cast<uint8*>(
242 resized_buffer->data()), HandleTransferCompletion, this, timeout); 253 resized_buffer->data()), HandleTransferCompletion, this, timeout);
243 SubmitTransfer(transfer, USB_TRANSFER_CONTROL, resized_buffer, resized_length, 254 SubmitTransfer(transfer, USB_ENDPOINT_CONTROL, resized_buffer, resized_length,
244 callback); 255 callback);
245 } 256 }
246 257
247 void UsbDevice::BulkTransfer(const TransferDirection direction, 258 void UsbDevice::BulkTransfer(const UsbInterfaceDirection direction,
248 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, 259 const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
249 const unsigned int timeout, const UsbTransferCallback& callback) { 260 const unsigned int timeout, const UsbTransferCallback& callback) {
250 CheckDevice(); 261 CheckDevice();
251 262
252 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); 263 struct libusb_transfer* const transfer = libusb_alloc_transfer(0);
253 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; 264 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
254 libusb_fill_bulk_transfer(transfer, handle_, new_endpoint, 265 libusb_fill_bulk_transfer(transfer, handle_, new_endpoint,
255 reinterpret_cast<uint8*>(buffer->data()), length, 266 reinterpret_cast<uint8*>(buffer->data()), length,
256 HandleTransferCompletion, this, timeout); 267 HandleTransferCompletion, this, timeout);
257 SubmitTransfer(transfer, USB_TRANSFER_BULK, buffer, length, callback); 268 SubmitTransfer(transfer, USB_ENDPOINT_BULK, buffer, length, callback);
258 } 269 }
259 270
260 void UsbDevice::InterruptTransfer(const TransferDirection direction, 271 void UsbDevice::InterruptTransfer(const UsbInterfaceDirection direction,
261 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, 272 const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
262 const unsigned int timeout, const UsbTransferCallback& callback) { 273 const unsigned int timeout, const UsbTransferCallback& callback) {
263 CheckDevice(); 274 CheckDevice();
264 275
265 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); 276 struct libusb_transfer* const transfer = libusb_alloc_transfer(0);
266 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; 277 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
267 libusb_fill_interrupt_transfer(transfer, handle_, new_endpoint, 278 libusb_fill_interrupt_transfer(transfer, handle_, new_endpoint,
268 reinterpret_cast<uint8*>(buffer->data()), length, 279 reinterpret_cast<uint8*>(buffer->data()), length,
269 HandleTransferCompletion, this, timeout); 280 HandleTransferCompletion, this, timeout);
270 SubmitTransfer(transfer, USB_TRANSFER_INTERRUPT, buffer, length, callback); 281 SubmitTransfer(transfer, USB_ENDPOINT_INTERRUPT, buffer, length, callback);
271 } 282 }
272 283
273 void UsbDevice::IsochronousTransfer(const TransferDirection direction, 284 void UsbDevice::IsochronousTransfer(const UsbInterfaceDirection direction,
274 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, 285 const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
275 const unsigned int packets, const unsigned int packet_length, 286 const unsigned int packets, const unsigned int packet_length,
276 const unsigned int timeout, const UsbTransferCallback& callback) { 287 const unsigned int timeout, const UsbTransferCallback& callback) {
277 CheckDevice(); 288 CheckDevice();
278 289
279 const uint64 total_length = packets * packet_length; 290 const uint64 total_length = packets * packet_length;
280 CHECK(packets <= length && total_length <= length) << 291 CHECK(packets <= length && total_length <= length) <<
281 "transfer length is too small"; 292 "transfer length is too small";
282 293
283 struct libusb_transfer* const transfer = libusb_alloc_transfer(packets); 294 struct libusb_transfer* const transfer = libusb_alloc_transfer(packets);
284 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; 295 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
285 libusb_fill_iso_transfer(transfer, handle_, new_endpoint, 296 libusb_fill_iso_transfer(transfer, handle_, new_endpoint,
286 reinterpret_cast<uint8*>(buffer->data()), length, packets, 297 reinterpret_cast<uint8*>(buffer->data()), length, packets,
287 HandleTransferCompletion, this, timeout); 298 HandleTransferCompletion, this, timeout);
288 libusb_set_iso_packet_lengths(transfer, packet_length); 299 libusb_set_iso_packet_lengths(transfer, packet_length);
289 300
290 SubmitTransfer(transfer, USB_TRANSFER_ISOCHRONOUS, buffer, length, callback); 301 SubmitTransfer(transfer, USB_ENDPOINT_ISOCHRONOUS, buffer, length, callback);
291 } 302 }
292 303
293 void UsbDevice::CheckDevice() { 304 void UsbDevice::CheckDevice() {
294 DCHECK(handle_) << "Device is already closed."; 305 DCHECK(handle_) << "Device is already closed.";
295 } 306 }
296 307
297 void UsbDevice::SubmitTransfer(PlatformUsbTransferHandle handle, 308 void UsbDevice::SubmitTransfer(PlatformUsbTransferHandle handle,
298 UsbTransferType transfer_type, 309 UsbEndpointType transfer_type,
299 net::IOBuffer* buffer, 310 net::IOBuffer* buffer,
300 const size_t length, 311 const size_t length,
301 const UsbTransferCallback& callback) { 312 const UsbTransferCallback& callback) {
302 Transfer transfer; 313 Transfer transfer;
303 transfer.transfer_type = transfer_type; 314 transfer.transfer_type = transfer_type;
304 transfer.buffer = buffer; 315 transfer.buffer = buffer;
305 transfer.length = length; 316 transfer.length = length;
306 transfer.callback = callback; 317 transfer.callback = callback;
307 318
308 { 319 {
309 base::AutoLock lock(lock_); 320 base::AutoLock lock(lock_);
310 transfers_[handle] = transfer; 321 transfers_[handle] = transfer;
311 libusb_submit_transfer(handle); 322 libusb_submit_transfer(handle);
312 } 323 }
313 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698