ubuntu14.04 adb搜索不到设备的问题

环境:ubuntu14.04虚拟机

最近做android系统开发,adb时不时的找不到设备,如下:

什么也没有,莫名其妙,浪费了不少时间。最近任务没那么紧张,这个问题又冒出来了。这次下决心要找到原因。这次从adb原理着手分析,下载了adb进行跟踪,有下面一段代码

static void find_usb_device(const char *base,
        void (*register_device_callback)
                (const char *, unsigned char, unsigned char, int, int, unsigned))
{
    char busname[32], devname[32];
    unsigned char local_ep_in, local_ep_out;
    DIR *busdir , *devdir ;
    struct dirent *de;
    int fd ;

    busdir = opendir(base);
    if(busdir == 0) return;

    while((de = readdir(busdir)) != 0) {
        if(badname(de->d_name)) continue;

        snprintf(busname, sizeof busname, "%s/%s", base, de->d_name);
        devdir = opendir(busname);
        if(devdir == 0) continue;

        DBGX("[ scanning %s ]\n", busname);
        while((de = readdir(devdir))) {
            unsigned char devdesc[4096];
            unsigned char* bufptr = devdesc;
            unsigned char* bufend;
            struct usb_device_descriptor* device;
            struct usb_config_descriptor* config;
            struct usb_interface_descriptor* interface;
            struct usb_endpoint_descriptor *ep1, *ep2;
            unsigned zero_mask = 0;
            unsigned vid, pid;
            size_t desclength;

            if(badname(de->d_name)) continue;
            snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);

            if(known_device(devname)) {
                DBGX("skipping %s\n", devname);
                continue;
            }

            DBGX("[ scanning %s ]\n", devname);
            if((fd = unix_open(devname, O_RDONLY)) < 0) {
                continue;
            }

            desclength = adb_read(fd, devdesc, sizeof(devdesc));
            bufend = bufptr + desclength;

                // should have device and configuration descriptors, and atleast two endpoints
            if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
                D("desclength %d is too small\n", desclength);
                adb_close(fd);
                continue;
            }

            device = (struct usb_device_descriptor*)bufptr;
            bufptr += USB_DT_DEVICE_SIZE;

            if((device->bLength != USB_DT_DEVICE_SIZE) || (device->bDescriptorType != USB_DT_DEVICE)) {
                adb_close(fd);
                continue;
            }

            vid = device->idVendor;
            pid = device->idProduct;
            DBGX("[ %s is V:%04x P:%04x ]\n", devname, vid, pid);

                // should have config descriptor next
            config = (struct usb_config_descriptor *)bufptr;
            bufptr += USB_DT_CONFIG_SIZE;
            if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {
                D("usb_config_descriptor not found\n");
                adb_close(fd);
                continue;
            }

                // loop through all the descriptors and look for the ADB interface
            while (bufptr < bufend) {
                unsigned char length = bufptr[0];
                unsigned char type = bufptr[1];

                if (type == USB_DT_INTERFACE) {
                    interface = (struct usb_interface_descriptor *)bufptr;
                    bufptr += length;

                    if (length != USB_DT_INTERFACE_SIZE) {
                        D("interface descriptor has wrong size\n");
                        break;
                    }

                    DBGX("bInterfaceClass: %d,  bInterfaceSubClass: %d,"
                         "bInterfaceProtocol: %d, bNumEndpoints: %d\n",
                         interface->bInterfaceClass, interface->bInterfaceSubClass,
                         interface->bInterfaceProtocol, interface->bNumEndpoints);

                    if (interface->bNumEndpoints == 2 &&
                            is_adb_interface(vid, pid, interface->bInterfaceClass,
                            interface->bInterfaceSubClass, interface->bInterfaceProtocol))  {

                        DBGX("looking for bulk endpoints\n");
                            // looks like ADB...
                        ep1 = (struct usb_endpoint_descriptor *)bufptr;
                        bufptr += USB_DT_ENDPOINT_SIZE;
                        ep2 = (struct usb_endpoint_descriptor *)bufptr;
                        bufptr += USB_DT_ENDPOINT_SIZE;

                        if (bufptr > devdesc + desclength ||
                            ep1->bLength != USB_DT_ENDPOINT_SIZE ||
                            ep1->bDescriptorType != USB_DT_ENDPOINT ||
                            ep2->bLength != USB_DT_ENDPOINT_SIZE ||
                            ep2->bDescriptorType != USB_DT_ENDPOINT) {
                            D("endpoints not found\n");
                            break;
                        }

                            // both endpoints should be bulk
                        if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
                            ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
                            D("bulk endpoints not found\n");
                            continue;
                        }
                            /* aproto 01 needs 0 termination */
                        if(interface->bInterfaceProtocol == 0x01) {
                            zero_mask = ep1->wMaxPacketSize - 1;
                        }

                            // we have a match.  now we just need to figure out which is in and which is out.
                        if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
                            local_ep_in = ep1->bEndpointAddress;
                            local_ep_out = ep2->bEndpointAddress;
                        } else {
                            local_ep_in = ep2->bEndpointAddress;
                            local_ep_out = ep1->bEndpointAddress;
                        }

                        register_device_callback(devname, local_ep_in, local_ep_out,
                                interface->bInterfaceNumber, device->iSerialNumber, zero_mask);
                        break;
                    }
                } else {
                    bufptr += length;
                }
            } // end of while

            adb_close(fd);
        } // end of devdir while
        closedir(devdir);
    } //end of busdir while
    closedir(busdir);
}

void* device_poll_thread(void* unused)
{
    D("Created device thread\n");
    for(;;) {
            /* XXX use inotify */
        find_usb_device("/dev/bus/usb", register_device);
        kick_disconnected_devices();
        sleep(1);
    }
    return NULL;
}

void usb_init()
{
    adb_thread_t tid;
    struct sigaction    actions;

    memset(&actions, 0, sizeof(actions));
    sigemptyset(&actions.sa_mask);
    actions.sa_flags = 0;
    actions.sa_handler = sigalrm_handler;
    sigaction(SIGALRM,& actions, NULL);

    if(adb_thread_create(&tid, device_poll_thread, NULL)){
        fatal_errno("cannot create input thread");
    }
}

大概的原理是adb会搜索"/dev/bus/usb"目录下所有的设备节点,打开并读取节点的设备描述符信息,找到adb设备。跟踪发现有个026的设备打开失败了,这个026设备正是adb设备,为什么打开失败了呢?看下面

原来这个设备所在组是audio,其他用户只读权限都没有,而我正好符合其他用户。到这里肯定知道怎么解决这个问题了,把自己添加到audio用户组问题就解决了。如下

貌似需要重启shell才会生效,再搜索下试试

 

果然OK了!!! 

这里我们在跟踪一下,找一下这个文件是哪条规则创建的,首先lsusb看一下新加入的usb设备,如下

 通过插拔知道Bus 001 Device 026: ID 2207:0006这个设备是adb设备,001总线,026节点,vendor是2207,product是0006,搜索一下rules,如下

 正好有这个条目,mode是660,原来就是它创建的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值