梳理USB port口检测设备

首先梳理一下usb设备的检测过程:
当usb设备接到port时,控制器会监测到该port电平状态发生改变,继而产生中断
port状态中断函数:handle_port_status
中断函数做了两件事:
第一件处理当前中断
第二件继续轮询该port状态

第一件事:使用tasklet中断下半部处理,然后使用工作队列创建出设备
    else if (high_prio_bh)                            // 同步传输或中断传输
        tasklet_hi_schedule(&bh->bh);
    else
        tasklet_schedule(&bh->bh);            // 控制传输或批量传输
tasklet执行usb_giveback_urb_bh,继而会执行urb的complete_fn。对于hub,complete_fn为hub_irq
hub_irq会执行唤醒工作队列hub_wq queue_work(hub_wq, &hub->events)
执行hub_event,然后故事就开始了。

第二件事:唤起定时器函数hcd->rh_timer - rh_timer_func - usb_hcd_poll_rh_status

插入鼠标获取usbmon

第一部分port相关包

ffffffa0e8a9af00 2329250566 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <    USB_RT_PORT    | IN
ffffffa0e8a9af00 2329250601 C Ci:3:001:0 0 4 = 01010100
ffffffa0e8a9af00 2329250614 S Co:3:001:0 s 23 01 0010 0001 0000 0
ffffffa0e8a9af00 2329250643 C Co:3:001:0 0 0
ffffffa0e8a9af00 2329250685 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9af00 2329250709 C Ci:3:001:0 0 4 = 01010000
ffffffa0e8a9af00 2329284024 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9af00 2329284053 C Ci:3:001:0 0 4 = 01010000
ffffffa0e8a9af00 2329320017 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9af00 2329320044 C Ci:3:001:0 0 4 = 01010000
ffffffa0e8a9af00 2329356036 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9af00 2329356079 C Ci:3:001:0 0 4 = 01010000
ffffffa0e8a9af00 2329392022 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9af00 2329392054 C Ci:3:001:0 0 4 = 01010000
ffffffa0e8a9af00 2329392417 S Co:3:001:0 s 23 03 0004 0001 0000 0
ffffffa0e8a9af00 2329392446 C Co:3:001:0 0 0
ffffffa0e8a9b000 2329460039 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9b000 2329460080 C Ci:3:001:0 0 4 = 03031000
ffffffa0e8a9b000 2329460108 S Co:3:001:0 s 23 01 0014 0001 0000 0
ffffffa0e8a9b000 2329460134 C Co:3:001:0 0 0
ffffffa0e8a9af00 2329520737 S Ci:3:000:0 s 80 06 0100 0000 0040 64 <
ffffffa0e8a9af00 2329524946 C Ci:3:000:0 0 18 = 12011001 00000008 3a091025 00010102 0001  // 鼠标设备描述符
ffffffa0e8a9af00 2329524971 S Co:3:001:0 s 23 03 0004 0001 0000 0
ffffffa0e8a9af00 2329525005 C Co:3:001:0 0 0
ffffffa0e8a9af00 2329592022 S Ci:3:001:0 s a3 00 0000 0001 0004 4 <
ffffffa0e8a9af00 2329592071 C Ci:3:001:0 0 4 = 03031000
ffffffa0e8a9af00 2329592081 S Co:3:001:0 s 23 01 0014 0001 0000 0
ffffffa0e8a9af00 2329592101 C Co:3:001:0 0 0
X3 为port操作
struct usb_ctrlrequest {
    __u8 bRequestType;   方向 in:80 / out:0
#define USB_DIR_OUT            0        /* to device */
#define USB_DIR_IN            0x80        /* to host */
#define USB_RT_PORT    (USB_TYPE_CLASS | USB_RECIP_OTHER)
#define USB_TYPE_CLASS            (0x01 << 5)
#define USB_RECIP_OTHER            0x03
    __u8 bRequest;                描述符操作
#define USB_REQ_GET_STATUS        0x00
#define USB_REQ_CLEAR_FEATURE        0x01
#define USB_REQ_SET_FEATURE        0x03
    __le16 wValue;                描述符类型
#define HUB_PORT_STATUS        0
#define HUB_PORT_PD_STATUS    1
#define HUB_EXT_PORT_STATUS    2
    __le16 wIndex;                // port号
    __le16 wLength;
} __attribute__ ((packed));
上述包来自hub_port_init中的hub_port_reset。

usb_control_msg 中会做如下填充
    struct usb_ctrlrequest *dr;
    dr->bRequestType = requesttype;
    dr->bRequest = request;
    dr->wValue = cpu_to_le16(value);
    dr->wIndex = cpu_to_le16(index);
    dr->wLength = cpu_to_le16(size);
其中value的组成:(type << 8) + index,index为port index号

第二部分鼠标相关包

010devnum为鼠标 :鼠标读取配置部分
ffffffa0e8a9ae00 2329672054 S Ci:3:010:0 s 80 06 0100 0000 0012 18 <
ffffffa0e8a9ae00 2329676947 C Ci:3:010:0 0 18 = 12011001 00000008 3a091025 00010102 0001
ffffffa0e8a9ae00 2329676984 S Ci:3:010:0 s 80 06 0200 0000 0009 9 <
ffffffa0e8a9ae00 2329680943 C Ci:3:010:0 0 9 = 09022200 010100a0 32
ffffffa0e8a9ae00 2329680966 S Ci:3:010:0 s 80 06 0200 0000 0022 34 <
ffffffa0e8a9ae00 2329687944 C Ci:3:010:0 0 34 = 09022200 010100a0 32090400 00010301 02000921 11010001 22340007 05810304
ffffffa0e8a9bc00 2329687999 S Ci:3:010:0 s 80 06 0300 0000 00ff 255 <
ffffffa0e8a9bc00 2329690944 C Ci:3:010:0 0 4 = 04030904
ffffffa0e8a9bc00 2329690978 S Ci:3:010:0 s 80 06 0302 0409 00ff 255 <
ffffffa0e8a9bc00 2329697943 C Ci:3:010:0 0 36 = 24035500 53004200 20004f00 70007400 69006300 61006c00 20004d00 6f007500
ffffffa0e8a9bc00 2329697979 S Ci:3:010:0 s 80 06 0301 0409 00ff 255 <
ffffffa0e8a9bc00 2329701944 C Ci:3:010:0 0 14 = 0e035000 69007800 41007200 7400
鼠标设置部分
ffffffa0e8a9bc00 2329705350 S Co:3:010:0 s 00 09 0001 0000 0000 0
ffffffa0e8a9bc00 2329706934 C Co:3:010:0 0 0
ffffffa0e8a9af00 2329707250 S Co:3:010:0 s 21 0a 0000 0000 0000 0
ffffffa0e8a9af00 2329708983 C Co:3:010:0 -32 0
ffffffa0e8a9af00 2329709023 S Ci:3:010:0 s 81 06 2200 0000 0034 52 <
ffffffa0e8a9af00 2329718945 C Ci:3:010:0 0 52 = 05010902 a1010901 a1000509 19012903 15002501 75019503 81027505 95018101
ffffffa0e8a9bf00 2329719592 S Ii:3:010:1 -115:8 4 <
知识点010为devnum,动态分配的,但是hub dev的devnum是固定的,hub为1
xhc有两个hub一个2.0,一个3.0,devnum都为1。不信?lsusb -tv
至于devnum为0,没研究过lsusb代码,个人猜测为xhc dev

struct usb_ctrlrequest {
    __u8 bRequestType;   方向 in:80 / out:0
#define USB_DIR_OUT            0        /* to device */
#define USB_DIR_IN            0x80        /* to host */
    __u8 bRequest;                描述符操作
#define USB_REQ_SET_ADDRESS        0x05
#define USB_REQ_GET_DESCRIPTOR        0x06
#define USB_REQ_SET_DESCRIPTOR        0x07
#define USB_REQ_GET_CONFIGURATION    0x08
#define USB_REQ_SET_CONFIGURATION    0x09
#define USB_REQ_GET_INTERFACE        0x0A
#define USB_REQ_SET_INTERFACE        0x0B
    __le16 wValue;                描述符类型
#define USB_DT_DEVICE            0x01
#define USB_DT_CONFIG            0x02
#define USB_DT_STRING            0x03
#define USB_DT_INTERFACE        0x04
#define USB_DT_ENDPOINT            0x05
    __le16 wIndex;               ep号
    __le16 wLength;
} __attribute__ ((packed));

usb_control_msg 中会做如下填充
    struct usb_ctrlrequest *dr;
    dr->bRequestType = requesttype;
    dr->bRequest = request;
    dr->wValue = cpu_to_le16(value);
    dr->wIndex = cpu_to_le16(index);
    dr->wLength = cpu_to_le16(size);
其中value的组成:(type << 8) + index,index为ep index号

第一个包 18byte 是读取usb_device_descriptor
80 06 0100 0000 0012
第二个包 9byte 是读取usb_config_descriptor
80 06 0200 0000 0009
第三个包 32byte    是读取所有的配置信息
80 06 0200 0000 0022                
第四 五 六个包 255byte,读取string,ep0,ep1_in,ep2_in,三个ep
80 06 0300 0000 00ff
80 06 0302 0409 00ff
80 06 0301 0409 00ff
第七个包 是设置ep1_out配置
00 09 0001 0000 0000
第八个包
21 0a 0000 0000 0000
第九个包
81 06 2200 0000 0034
上述包都为setup包

hub_port_init 中实现了DEVICE包的发送,发送位置为
usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);

usb_enumerate_device实现CONFIG和STRING包发送。
usb_get_configuratio(udev)
usb_cache_string(udev, udev->descriptor.iProduct);
usb_cache_string(udev, udev->descriptor.iManufacturer);
usb_cache_string(udev, udev->descriptor.iSerialNumber);

来来来对比一下:
lsusb -s 003:005 -v

Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x093a Pixart Imaging, Inc.
  idProduct          0x2510 Optical Mouse
  bcdDevice            1.00
  iManufacturer           1 PixArt
  iProduct                2 USB Optical Mouse
  iSerial                 0
  bNumConfigurations      1
对比一下返回
12011001 00000008 3a091025 00010102 0001

Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0022
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
对比一下返回
09022200 010100a0
协议包中数据以大端形式返回

usb杂谈之获取设备信息——举例鼠标urb相关推荐

  1. html5获取设备信息 视频,设备信息的管理(Device) ---- HTML5+

    Device模块管理设备信息,用于获取手机设备的相关信息,如IMEI.IMSI.型号.厂商等.通过plus.device获取设备信息管理对象. 应用场景:打电话,铃声提醒,震动提醒,音量设置,查看设备 ...

  2. Linux系统下自动搜索USB摄像头地址及设备信息

    Linux系统下自动搜索USB摄像头地址及设备信息 在进行到多个USB摄像头开发时,会涉及到获取摄像头地址及设备信息问题. 一般USB摄像头的设备信息是固定的,我们基于设备信息,就可以在软件开发时进行 ...

  3. Windows,Android设备刷机(重装系统)时遇到USB读取不到设备信息(设备驱动异常)问题及解决办法

    Windows,Android设备刷机(重装系统)时遇到USB读取不到设备信息(设备驱动异常)问题及解决办法 前言 当刷Android系统时,我们要进入boot模式,**adb reboot boot ...

  4. 小程序获取设备信息以及实现短信验证码登录

    1.微信小程序 获取设备信息 API实例详解 https://www.jb51.net/article/93994.htm 2.微信小程序发送短信验证码完整实例 https://blog.csdn.n ...

  5. android异常信息,Android 获取设备信息 异常

    /**获取设备信息 * @param c * @return */ public static void setDeviceInfo(Context c,RequestParams params){ ...

  6. HTML5+获取设备信息

    阿里云低价服务器1折特惠,优惠爽翻天,点我立即低价购买 Device模块管理设备信息,用于获取手机设备的相关信息,如IMEI.IMSI.型号.厂商等.通过plus.device获取设备信息管理对象. ...

  7. 人脸识别/车牌识别视频智能分析系统EasyCVR通过接口GetApiV1Devices调用获取设备信息不成功原因分析

    EasyCVR视频智能分析平台支持人脸识别和车牌识别,已经在很多项目中落地.同时,EasyCVR支持很多不同协议的设备接入,包括RTSP.GB28181.Ehome.海康SDK.大华SDK等协议. 用 ...

  8. Flutter中使用device_info获取设备信息

    1. 安装插件 配置 device_info 插件. dependencies:flutter:sdk: flutter# 设备信息device_info: ^2.0.2 在pubspec.yaml中 ...

  9. uniGUI获取设备信息

    有时候我们需要知道客户是使用什么设备登录的系统,在uniGUI中可以通过UniApplication.UniPlatform来获取. 简单记录一下,uniGUI的资料不太多,需要深入了解的,请多看DE ...

  10. java 自己实现 解析处理user-agent 获取设备信息 ip-ua转化归因

    前景提要 最近在做app投放的转化归因,几个搜索平台并不一定能获取到muid,于是需要用到ip-ua归因模式 网上粗略搜了一下,发现许多文章ua处理用的uaparser又或者user-agent-ut ...

最新文章

  1. SPI 的主模式和从模式
  2. gorm crud简单代码示例
  3. android模拟器EditText 不能用物理键盘输入,也不能用电脑键盘输入
  4. What does SAP UI5 bindItem occurs
  5. 假期周进度总计(四)
  6. centos 搭建jenkins+git+maven
  7. ubuntu编译mysql源码
  8. linux内核源码 -- list链表
  9. xssfworkbook excel打开为空白_「Excel」轻松运用 Excel 之“Excel 选项”的 4 个设置
  10. python将excel导入生成矩阵_Python导入数值型Excel数据并生成矩阵操作
  11. SFS2X 例子(java 扩展加as 客户端)
  12. web表格增删改_白话django之数据的增删改
  13. WPS安装office自定义项安装期间出错
  14. Ant安装与配置build.xml文件说明
  15. 软件测试专业川内大学,四川大学分析测试中心
  16. 如何在Google Play 当中使用ASO?google play aso
  17. 不要轻易在简历上写我热爱编程,我热爱学习
  18. 闪电贷攻击攻击屡试不爽,DeFi一周被盗超1600万美元
  19. MDClub一个漂亮轻量的开源论坛系统
  20. TP6 + Layui实现无限极分类

热门文章

  1. 爬取豆瓣电影TOP100
  2. html小球与边框碰撞反弹,通过JS如何实现多个小球碰撞反弹
  3. mobile terminal 笔记
  4. 面经个人向(算法岗)
  5. 【web素材】02-10款大气的购物商城网站模板
  6. 微信游戏推荐系统大揭秘
  7. Java架构师技术进阶路线图详解
  8. cad查看_CAD快速看图 for mac(CAD图纸查看工具) v4.3.7中文版
  9. x61 linux 驱动 无线网卡,联想ThinkPad X61无线网卡驱动
  10. 计算机指数函数符号,常用数学符号大全(注音及注解)