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

本文介绍了如何在一款名为Broncho的手机上实现RNDIS/USBNet驱动,使其能在Linux和Windows环境下作为网络设备使用。文章详细记录了调试过程中遇到的问题及解决办法。
AI助手已提取文章相关产品:
手机探索者开发实录—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. Bus003Device063:ID0bb4:0bceHighTechComputerCorp.
  2. DeviceDescriptor:
  3. bLength18
  4. bDescriptorType1
  5. bcdUSB2.00
  6. bDeviceClass239MiscellaneousDevice
  7. bDeviceSubClass1?
  8. bDeviceProtocol1MicrosoftActiveSync
  9. bMaxPacketSize064
  10. idVendor0x0bb4HighTechComputerCorp.
  11. idProduct0x0bce
  12. bcdDevice0.00
  13. iManufacturer1HTC
  14. iProduct2GenericRNDIS
  15. iSerial300846335-3781-0103-4800-0050bf3f5173
  16. bNumConfigurations1
  17. ConfigurationDescriptor:
  18. bLength9
  19. bDescriptorType2
  20. wTotalLength62
  21. bNumInterfaces2
  22. bConfigurationValue1
  23. iConfiguration0
  24. bmAttributes0xc0
  25. SelfPowered
  26. MaxPower100mA
  27. InterfaceDescriptor:
  28. bLength9
  29. bDescriptorType4
  30. bInterfaceNumber0
  31. bAlternateSetting0
  32. bNumEndpoints1
  33. bInterfaceClass239MiscellaneousDevice
  34. bInterfaceSubClass1?
  35. bInterfaceProtocol1MicrosoftActiveSync
  36. iInterface0
  37. EndpointDescriptor:
  38. bLength7
  39. bDescriptorType5
  40. bEndpointAddress0x81EP1IN
  41. bmAttributes3
  42. TransferTypeInterrupt
  43. SynchTypeNone
  44. UsageTypeData
  45. wMaxPacketSize0x00081x8bytes
  46. bInterval1
  47. InterfaceDescriptor:
  48. bLength9
  49. bDescriptorType4
  50. bInterfaceNumber1
  51. bAlternateSetting0
  52. bNumEndpoints2
  53. bInterfaceClass10CDCData
  54. bInterfaceSubClass0Unused
  55. bInterfaceProtocol0
  56. iInterface0
  57. EndpointDescriptor:
  58. bLength7
  59. bDescriptorType5
  60. bEndpointAddress0x82EP2IN
  61. bmAttributes2
  62. TransferTypeBulk
  63. SynchTypeNone
  64. UsageTypeData
  65. wMaxPacketSize0x00401x64bytes
  66. bInterval0
  67. EndpointDescriptor:
  68. bLength7
  69. bDescriptorType5
  70. bEndpointAddress0x03EP3OUT
  71. bmAttributes2
  72. TransferTypeBulk
  73. SynchTypeNone
  74. UsageTypeData
  75. wMaxPacketSize0x00401x64bytes
  76. bInterval0


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

把rndis_control_intf的内容修改为:

  1. staticconststructusb_interface_descriptor
  2. rndis_control_intf={
  3. .bLength=sizeofrndis_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. #defineRNDIS_CONF_NR1

用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~~


您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值