connection.getFileDescriptor()
我正在使用 libusb-compat 和 libusb-1.0调试在 Android 上打开设备(在 Android 代码和文件描述符中授予的权限),但出现错误:
07-30 11:24:15.673: WARN/System.err(8934): libusb: 0.000122 error [op_get_config_descriptor] open '/dev/bus/usb/001/002' failed, ret=-1 errno=13
我找不到 errno 13 libusb.h
。
带有我的调试输出(fprintf)的初始化代码(来自 libusb-compat)是:
static int initialize_device(struct usb_device *dev)
{
libusb_device *newlib_dev = dev->dev;
int num_configurations;
size_t alloc_size;
int r;
int i;
/* Device descriptor is identical in both libs */
r = libusb_get_device_descriptor(newlib_dev, (struct libusb_device_descriptor *) &dev->descriptor); // Error here!
if (r < 0) {
usbi_err("error %d getting device descriptor", r);
return compat_err(r);
} else {
// 4ntoine
fprintf(stderr, "pid=%i vid=%i serial=%i\n",
dev->descriptor.idProduct, dev->descriptor.idVendor, dev->descriptor.iSerialNumber);
}
num_configurations = dev->descriptor.bNumConfigurations;
alloc_size = sizeof(struct usb_config_descriptor) * num_configurations;
dev->config = malloc(alloc_size);
if (!dev->config)
return -ENOMEM;
memset(dev->config, 0, alloc_size);
/* Even though structures are identical, we can't just use libusb-1.0's
* config descriptors because we have to store all configurations in
* a single flat memory area (libusb-1.0 provides separate allocations).
* we hand-copy libusb-1.0's descriptors into our own structures. */
// 4ntoine
fprintf(stderr, "%i configurations\n", num_configurations);
for (i = 0; i < num_configurations; i++) {
struct libusb_config_descriptor *newlib_config;
r = libusb_get_config_descriptor(newlib_dev, i, &newlib_config);
if (r < 0) {
// 4ntoine
fprintf(stderr, "failed to libusb_get_config_descriptor: %i\n", r);
clear_device(dev);
free(dev->config);
return compat_err(r);
}
// 4ntoine - print information
fprintf(stderr, "Interfaces: %i\n", (int)config->bNumInterfaces);
const libusb_interface *inter;
const libusb_interface_descriptor *interdesc;
const libusb_endpoint_descriptor *epdesc;
for(int i=0; i<(int)config->bNumInterfaces; i++) {
inter = &config->interface[i];
fprintf(stderr, "Number of alternate settings: %i\n", inter->num_altsetting;
for(int j=0; j<inter->num_altsetting; j++) {
interdesc = &inter->altsetting[j];
fprintf(stderr, "Interface Number: %i\n", (int)interdesc->bInterfaceNumber);
fprintf(stderr, "Number of endpoints: %i\n", (int)interdesc->bNumEndpoints);
for(int k=0; k<(int)interdesc->bNumEndpoints; k++) {
epdesc = &interdesc->endpoint[k];
fprintf(stderr, "Descriptor Type: %i\n", (int)epdesc->bDescriptorType);
fprintf(stderr, "EP Address: %i\n", (int)epdesc->bEndpointAddress);
}
}
}
r = copy_config_descriptor(dev->config + i, newlib_config);
libusb_free_config_descriptor(newlib_config);
if (r < 0) {
// 4ntoine
fprintf(stderr, "failed to copy_config_descriptor: %i\n", r);
clear_device(dev);
free(dev->config);
return r;
}
}
/* libusb doesn't implement this and it doesn't seem that important. If
* someone asks for it, we can implement it in v1.1 or later. */
dev->num_children = 0;
dev->children = NULL;
libusb_ref_device(newlib_dev);
return 0;
}
更新:我越来越接近解决我的问题。我发现 op_get_config_descriptor (linux_usbfs.c) 使用设备路径来使用 open() 获取 fd,但它已经从 Android 连接接收到,应该使用。所以我不得不更改代码以将 fd 传递给 op_get_config_descriptor() 并将其重命名为 op_get_config_descriptor2():
static int op_get_config_descriptor2(
struct libusb_device *dev,
uint8_t config_index,
unsigned char *buffer,
size_t len,
int *host_endian,
int fd)
{
char filename[PATH_MAX];
int _fd = fd;
int r;
/* Always read from usbfs: sysfs only has the active descriptor
* this will involve waking the device up, but oh well! */
/* FIXME: the above is no longer true, new kernels have all descriptors
* in the descriptors file. but its kinda hard to detect if the kernel
* is sufficiently new. */
// 4ntoine
if (_fd < 0) {
_get_usbfs_path(dev, filename);
_fd = open(filename, O_RDONLY);
if (_fd < 0) {
usbi_err(DEVICE_CTX(dev),
"open '%s' failed, ret=%d errno=%d", filename, _fd, errno);
return LIBUSB_ERROR_IO;
}
}
else {
usbi_dbg("using fd = %i\n", _fd);
}
r = get_config_descriptor(DEVICE_CTX(dev), _fd, config_index, buffer, len);
close(_fd);
return r;
}
现在的问题是找不到使用该 fd的USB设备(它通过 Unix 套接字传递给AVRDUDE,我检查它是否为正整数,所以我相信没关系):
lseek(fd, DEVICE_DESC_LENGTH, SEEK_SET)
返回负值
输出是:
07-30 15:39:08.723: WARN/System.err(30394): [ 07-30 15:39:08.723 30394: 1764 W/System.err ]
libusb: 0.004884 error [get_config_descriptor] seek failed ret=-1 errno=9
我该如何解决这个问题?