• 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 = (USB_DT_STRING << 8) | 0;
     82                 ctrl.wIndex = 0;
     83                 ctrl.wLength = sizeof(languages);
     84                 ctrl.data = 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
    ", strerror(errno));
     92 
     93                 printf("languageCount = %d
    ", 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 = (USB_DT_STRING << 8) | serial_index;
    101                     ctrl.wIndex = __le16_to_cpu(languages[i]);
    102                     ctrl.wLength = sizeof(buffer);
    103                     ctrl.data = 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
    ", serial);
    115                         break;
    116                     }
    117                     else if(result < 0)
    118                     {
    119                         printf("ioctl failed: %s
    ", strerror(errno));
    120                     }
    121                 }
    122             }
    123         }
    124         else
    125         {
    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 endpoints
    176             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 interface
    200             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_id
    221                         printf("get:
    devname = %s
    idVendor=0x%x idProduct=0x%x
    ",
    222                                 devname, vid, pid);
    223 
    224                         break;
    225                     }
    226                 } else {
    227                     bufptr += length;
    228                 }
    229             } // end of while
    230 
    231             close(fd);
    232         } // end of devdir while
    233         closedir(devdir);
    234     } //end of busdir while
    235     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
    ", va[i].adb_dev_path.c_str(), va[i].serial_index);
    244     }
    245 
    246     get_serial();
    247 
    248     return 0;
    249 }
  • 相关阅读:
    感谢燕玲,搞定了客商名称输入即开始检测是否存在
    一步一步学习sqlserverBI多维数据库建立
    sql语句创建文件夹、判断文件夹、创建数据库、表、
    自定义Silverlight DataGrid行列:Defining Columns for a Silverlight DataGrid
    精简版XP SP3安装IIS6,过程坎坷,以此文献给有需要的朋友
    SilverLight 4页面跳转大全(转载)
    如何修改.net framework(转载)
    定义silverlight报表样式Styling a Silverlight Chart
    Silverlight Toolkit DataGrid 单元格内容对齐样式
    一步一步学习sqlserver BI数据仓库设计
  • 原文地址:https://www.cnblogs.com/jojodru/p/4028892.html
Copyright © 2020-2023  润新知