zoukankan      html  css  js  c++  java
  • 手机探索者开发实录—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~~


  • 相关阅读:
    BZOJ 2034 【2009国家集训队】 最大收益
    vijos P1780 【NOIP2012】 开车旅行
    BZOJ 2115 【WC2011】 Xor
    BZOJ 3631 【JLOI2014】 松鼠的新家
    BZOJ 4717 改装
    BZOJ 2957 楼房重建
    BZOJ 4034 【HAOI2015】 T2
    BZOJ 1834 【ZJOI2010】 network 网络扩容
    BZOJ 2440 【中山市选2011】 完全平方数
    BZOJ 2733 【HNOI2012】 永无乡
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167624.html
Copyright © 2011-2022 走看看