首页 > 代码库 > adb设备,根据serial获取vid pid

adb设备,根据serial获取vid pid

使用adb devices命令,可以轻松获取到所有连接到PC的adb设备的serial值。

但是adb命令无法获取adb usb设备的vendor id和product id。

本程序根据adb协议,遍历usb设备,使用ioctrl获取serial和vid,pid,这样可以将serial和vid pid匹配起来。

Windows版本的实现可以根据adb_api.h实现,但是有一个问题,adb的服务会独占adb设备,如果adb服务正在运行,那么,这个实现是无法兑现功能的。

谁有好的办法,欢迎共享。Linux平台则无此限制。

下面提供Linux平台的实现,Windows的实现,因为受限于adb服务独占设备,就不贴出来了,谁有兴趣的,可以问我要代码。

具体Linux实现参见代码:

  1 #include <cstdio>  2 #include <cstdlib>  3 #include <cstring>  4   5 #include <unistd.h>  6 #include <sys/ioctl.h>  7 #include <sys/types.h>  8 #include <sys/stat.h>  9 #include <sys/time.h> 10 #include <dirent.h> 11 #include <fcntl.h> 12 #include <errno.h> 13 #include <ctype.h> 14  15 #include <linux/usbdevice_fs.h> 16 #include <linux/version.h> 17 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) 18 #include <linux/usb/ch9.h> 19 #else 20 #include <linux/usb_ch9.h> 21 #endif 22 #include <asm/byteorder.h> 23  24 #define ADB_CLASS              0xff 25 #define ADB_SUBCLASS           0x42 26 #define ADB_PROTOCOL           0x1 27  28 #include <string> 29 #include <vector> 30  31 typedef struct tag_devpath { 32     int serial_index; 33     std::string adb_dev_path; 34 }ADB_DEV; 35  36 std::vector<ADB_DEV> va; 37  38 inline int badname(const char *name) 39 { 40     while(*name) { 41         if(!isdigit(*name++)) return 1; 42     } 43     return 0; 44 } 45  46 int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) 47 { 48     if (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && 49             usb_protocol == ADB_PROTOCOL) { 50         return 1; 51     }    52  53     return 0; 54 } 55  56 int get_serial() 57 { 58     for(int i = 0; i < va.size(); ++i) 59     { 60         int fd = open(va[i].adb_dev_path.c_str(), O_RDWR); 61         if(fd > 0) 62         { 63             char serial[256]; 64             int n = 256; 65             int serial_index = va[i].serial_index; 66             serial[0] = 0; 67             memset(serial, 0, n); 68             if (serial_index) { 69                 struct usbdevfs_ctrltransfer  ctrl; 70                 __u16 buffer[128]; 71                 __u16 languages[128]; 72                 int i, result; 73                 int languageCount = 0; 74  75                 memset(languages, 0, sizeof(languages)); 76                 memset(&ctrl, 0, sizeof(ctrl)); 77  78                 // read list of supported languages 79                 ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE; 80                 ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; 81                 ctrl.wValue = http://www.mamicode.com/(USB_DT_STRING << 8) | 0; 82                 ctrl.wIndex = 0; 83                 ctrl.wLength = sizeof(languages); 84                 ctrl.data =http://www.mamicode.com/ languages; 85                 ctrl.timeout = 1000; 86  87                 result = ioctl(fd, USBDEVFS_CONTROL, &ctrl); 88                 if (result > 0) 89                     languageCount = (result - 2) / 2; 90                 else if(result < 0) 91                     printf("ioctl failed: %s\n", strerror(errno)); 92  93                 printf("languageCount = %d\n", languageCount); 94                 for (i = 1; i <= languageCount; i++) { 95                     memset(buffer, 0, sizeof(buffer)); 96                     memset(&ctrl, 0, sizeof(ctrl)); 97  98                     ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE; 99                     ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;100                     ctrl.wValue = http://www.mamicode.com/(USB_DT_STRING << 8) | serial_index;101                     ctrl.wIndex = __le16_to_cpu(languages[i]);102                     ctrl.wLength = sizeof(buffer);103                     ctrl.data =http://www.mamicode.com/ buffer;104                     ctrl.timeout = 1000;105 106                     result = ioctl(fd, USBDEVFS_CONTROL, &ctrl);107                     if (result > 0) {108                         int i;109                         // skip first word, and copy the rest to the serial string, changing shorts to bytes.110                         result /= 2;111                         for (i = 1; i < result; i++)112                             serial[i - 1] = __le16_to_cpu(buffer[i]);113                         serial[i - 1] = 0;114                         printf("serial: %s\n", serial);115                         break;116                     }117                     else if(result < 0)118                     {119                         printf("ioctl failed: %s\n", strerror(errno));120                     }121                 }122             }123         }124         else125         {126             printf("open %s failed: %s", va[i].adb_dev_path.c_str(), strerror(errno));127         }128     }129 130     return 0;131 }132 133 void find_usb_device(void)134 {135     const char* base = "/dev/bus/usb";136     char busname[32], devname[32];137     DIR *busdir , *devdir ;138     struct dirent *de;139     int fd ;140 141     busdir = opendir(base);142     if(busdir == 0) return;143 144     va.clear();145 146     while((de = readdir(busdir)) != 0) {147         if(badname(de->d_name)) continue;148 149         snprintf(busname, sizeof busname, "%s/%s", base, de->d_name);150         devdir = opendir(busname);151         if(devdir == 0) continue;152 153         while((de = readdir(devdir))) {154             unsigned char devdesc[4096];155             unsigned char* bufptr = devdesc;156             unsigned char* bufend;157             struct usb_device_descriptor* device;158             struct usb_config_descriptor* config;159             struct usb_interface_descriptor* interface;160             struct usb_endpoint_descriptor *ep1, *ep2;161             unsigned zero_mask = 0;162             unsigned vid, pid;163             size_t desclength;164 165             if(badname(de->d_name)) continue;166             snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);167 168             if((fd = open(devname, O_RDONLY)) < 0) {169                 continue;170             }171 172             desclength = read(fd, devdesc, sizeof(devdesc));173             bufend = bufptr + desclength;174 175             // should have device and configuration descriptors, and atleast two endpoints176             if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {177                 close(fd);178                 continue;179             }180 181             device = (struct usb_device_descriptor*)bufptr;182             bufptr += USB_DT_DEVICE_SIZE;183 184             if((device->bLength != USB_DT_DEVICE_SIZE) || (device->bDescriptorType != USB_DT_DEVICE)) {185                 close(fd);186                 continue;187             }188 189             vid = device->idVendor;190             pid = device->idProduct;191 192             config = (struct usb_config_descriptor *)bufptr;193             bufptr += USB_DT_CONFIG_SIZE;194             if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {195                 close(fd);196                 continue;197             }198 199                 // loop through all the descriptors and look for the ADB interface200             while (bufptr < bufend) {201                 unsigned char length = bufptr[0];202                 unsigned char type = bufptr[1];203 204                 if (type == USB_DT_INTERFACE) {205                     interface = (struct usb_interface_descriptor *)bufptr;206                     bufptr += length;207 208                     if (length != USB_DT_INTERFACE_SIZE) {209                         break;210                     }211 212                     if (is_adb_interface(interface->bInterfaceClass,213                             interface->bInterfaceSubClass, interface->bInterfaceProtocol))  {214 215                         ADB_DEV ad;216                         ad.serial_index = device->iSerialNumber;217                         ad.adb_dev_path = devname;218                         va.push_back(ad);219 220                         //get devname vendor_id product_id221                         printf("get:\ndevname = %s\nidVendor=0x%x idProduct=0x%x\n",222                                 devname, vid, pid);223 224                         break;225                     }226                 } else {227                     bufptr += length;228                 }229             } // end of while230 231             close(fd);232         } // end of devdir while233         closedir(devdir);234     } //end of busdir while235     closedir(busdir);236 }237 238 int main(void)239 {240     find_usb_device();241     for(int i = 0; i < va.size(); ++i)242     {243         printf("dev:%s ===> serial index: %d\n", va[i].adb_dev_path.c_str(), va[i].serial_index);244     }245 246     get_serial();247 248     return 0;249 }

 

adb设备,根据serial获取vid pid