• 手机探索者开发实录—rndis/usbnet


    手机探索者开发实录—rndis/usbnet

    转载时请注明出处和作者联系方式
    作者联系方式:李先静 <xianjimli at hotmail dot com>

    手机探索者(mobile explorer)通过几层抽象,让它不依赖于特定的传输方式,然而抽象就是抽象,一个抽象的面包是不能填饱肚子的,我们一定要有具体的实现。手机探索者(mobile explorer)先实现基于rndis/usbnet的传输方式,在linux PC上支持usbnet是一件非常自然的事情,然而windows似乎并不认识我们的broncho手机:找不到相应驱动的程序,按网上的介绍去做也不凑效。

    虽然看了两周Windows DDK的资料,我还是没有信心和时间去写自己的usbnet驱动程序。没办法,最后决定把broncho伪装成一个window mobile手机,我看过RNDIS的资料和代码,了解它的基本原理,知道实现起来并不难。尽管linux下RNDIS的作者在代码中抱怨RNDIS的SPEC太模糊,但他对Windows mobile手机支持还是比较完善的。

    RNDIS也有设备端的实现,我想要模拟window mobile手机是轻而易举的事。不过还是遇到了点麻烦,在broncho上启用了RNDIS之后,linux PC仍然把它识别为一个普通usbnet设备,我发现它总是匹配不到rndis_host驱动。只好找来一台windows mobile手机,插到linux PC上,然后分析它的USB配置,其内容如下:

    1. Bus 003 Device 063: ID 0bb4:0bce High Tech Computer Corp.
    2. Device Descriptor:
    3.   bLength                18
    4.   bDescriptorType         1
    5.   bcdUSB               2.00
    6.   bDeviceClass          239 Miscellaneous Device
    7.   bDeviceSubClass         1 ?
    8.   bDeviceProtocol         1 Microsoft ActiveSync
    9.   bMaxPacketSize0        64
    10.   idVendor           0x0bb4 High Tech Computer Corp.
    11.   idProduct          0x0bce
    12.   bcdDevice            0.00
    13.   iManufacturer           1 HTC
    14.   iProduct                2 Generic RNDIS
    15.   iSerial                 3 00846335-3781-0103-4800-0050bf3f5173
    16.   bNumConfigurations      1
    17.   Configuration Descriptor:
    18.     bLength                 9
    19.     bDescriptorType         2
    20.     wTotalLength           62
    21.     bNumInterfaces          2
    22.     bConfigurationValue     1
    23.     iConfiguration          0
    24.     bmAttributes         0xc0
    25.       Self Powered
    26.     MaxPower              100mA
    27.     Interface Descriptor:
    28.       bLength                 9
    29.       bDescriptorType         4
    30.       bInterfaceNumber        0
    31.       bAlternateSetting       0
    32.       bNumEndpoints           1
    33.       bInterfaceClass       239 Miscellaneous Device
    34.       bInterfaceSubClass      1 ?
    35.       bInterfaceProtocol      1 Microsoft ActiveSync
    36.       iInterface              0
    37.       Endpoint Descriptor:
    38.         bLength                 7
    39.         bDescriptorType         5
    40.         bEndpointAddress     0x81  EP 1 IN
    41.         bmAttributes            3
    42.           Transfer Type            Interrupt
    43.           Synch Type               None
    44.           Usage Type               Data
    45.         wMaxPacketSize     0x0008  1x 8 bytes
    46.         bInterval               1
    47.     Interface Descriptor:
    48.       bLength                 9
    49.       bDescriptorType         4
    50.       bInterfaceNumber        1
    51.       bAlternateSetting       0
    52.       bNumEndpoints           2
    53.       bInterfaceClass        10 CDC Data
    54.       bInterfaceSubClass      0 Unused
    55.       bInterfaceProtocol      0
    56.       iInterface              0
    57.       Endpoint Descriptor:
    58.         bLength                 7
    59.         bDescriptorType         5
    60.         bEndpointAddress     0x82  EP 2 IN
    61.         bmAttributes            2
    62.           Transfer Type            Bulk
    63.           Synch Type               None
    64.           Usage Type               Data
    65.         wMaxPacketSize     0x0040  1x 64 bytes
    66.         bInterval               0
    67.       Endpoint Descriptor:
    68.         bLength                 7
    69.         bDescriptorType         5
    70.         bEndpointAddress     0x03  EP 3 OUT
    71.         bmAttributes            2
    72.           Transfer Type            Bulk
    73.           Synch Type               None
    74.           Usage Type               Data
    75.         wMaxPacketSize     0x0040  1x 64 bytes
    76.         bInterval               0


    它有两个接口,第一个接口的InterfaceClass和InterfaceSubClass表明它是一个特殊的RNDIS(即ActiveSync),第二个接口表明它是一个普通的CDC设备,也就是usbnet。我按这个配置修改了drivers/usb/gadget/ether.c。

    把rndis_control_intf的内容修改为:

    1. static const struct usb_interface_descriptor
    2. rndis_control_intf = {
    3.     .bLength =              sizeof rndis_control_intf,
    4.     .bDescriptorType =      USB_DT_INTERFACE,
    5.     .bInterfaceNumber =     0,
    6.     .bNumEndpoints =        1,
    7.     .bInterfaceClass =      USB_CLASS_MISC,
    8.     .bInterfaceSubClass =   1,
    9.     .bInterfaceProtocol =   1,
    10.     .iInterface =           STRING_RNDIS_CONTROL,
    11. };


    当启用RNDIS时,ether.c中USB设备有两个配置,第一个RNDIS,第二个是标准CDC,不知道为何Linux PC总是优先匹配到CDC驱动,最后我只好把它修改为一个配置了:

    先把配置的个数定义成一个宏,如果有问题,改回来比较容易。
    1. #define RNDIS_CONF_NR 1

    用RNDIS_CONF_NR替换配置的个数,修改的代码有:

    1. device_desc.bNumConfigurations=RNDIS_CONF_NR
    2. if (rndis)
    3.         device_desc.bNumConfigurations = RNDIS_CONF_NR;
    4. if (rndis)
    5.         dev_qualifier.bNumConfigurations = RNDIS_CONF_NR;


    重新把broncho手机插入到Linux PC上,Linux PC可以正确加载RNDIS_HOST驱动,然而总是告诉我RNDIS初始化失败。失败的原因居然是pipe broken,这让我百思不得其解,RNDIS是通过ep0发送的,这是任何USB设备都会支持的,怎么是pipe broken呢,读了半天USB驱动的代码确认没有什么问题,然后在broncho的UDC的中断打出调试信息,确认收到了初始化的消息,进入一步跟踪到手机RNDIS驱动程序中,也确定收到了初始化消息。失败的原因是rndis没有被激活,让rndis_active函数始终返回TRUE,一切OK了。

    把broncho手机插入装有activesync的windows,windows把broncho识别为windows mobile device,activesync也能识别broncho了,用telnet连接到broncho手机中,能够进入终端状态。

    呵,一切OK了,因为被pipe broken这个错误所迷惑,我读了两天代码才找到原因,结果只需要修改几行代码就行了。

    ~~end~~


  • 相关阅读:
    Task10 文本预处理
    Task09 批量归一化
    Task06 Basic of CNN
    Task05 梯度消失和梯度爆炸
    Task 04 过拟合,欠拟合及其解决方案
    机器学习 Task 03 多层感知机
    机器学习 task2 softmax与分类模型
    异步与闭包与fetch
    baidu API
    my own JSON
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167624.html
Copyright © 2020-2023  润新知