首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。