嵌入式技术论坛
直播中

刘埃生

7年用户 1654经验值
私信 关注
[经验]

基于CherryUSB适配RNDIS调试笔记记录

前言

原项目中需要用到RNDIS,移植了一版,效果不是很好,项目最后没用上
现在计划重新基于CherryUSB来适配,记录一些调试笔记。

计划

因有一些USB基础,因此打算以突击的方式来推进。

开发环境


干活前先做准备工作,了解到目前CherryUSB HOST驱动适配相对较好的是STM32,刚好有个429开发板,因此就打算以这个板子来进行开发。
示例工程可以开箱即用,同时可以SWD仿真调试,应该能给后期调试带来方便。

网卡

RNDIS网卡选用的Air724UG,先插好4G SIM卡,接在电脑上确认能正常识别为RNDIS并能上网。建议抄下设备所有相关的信息,以方便后面调试时对比。



USB抓包分析仪

还在路上,现在居家办公,看起来一时半会快递不会送了

调试过程


抓包
没有硬件抓包,就先来软件抓个包吧,Wireshark就可以,好用得很。

上板枚举

把我的4G网卡插到开发板上,提示

分析感觉不对,至少也得是full speed才对,low speed后面也无法切成高速。
大佬建议先插好网卡,再启动软件这边来枚举。

之前是自动启动USB的,现在改为命令启动,插好网卡后2秒后,再手动启动USB。
看起来都正常了,至少枚举过程是完成了。
项目中用的话,估计要从供电和开机过程中来找问题,不然怕起不来。

class驱动

根据现有calss驱动,照葫芦画瓢。

classwirelessu***h_rndis.c

core/u***h_core.c
发现Class:0xe0,Subclass:0x01,Protocl:0x03里面只有一个int endpoint。
真正传输数据是在Class:0x0a,Subclass:0x00,Protocl:0x00这个是CDC_DATA,
里面有bulkin和bulkout。
于是我机智的注册了2个class用于快速测试。

依样学样,在connect中alloc好class driver和bulk endpoint后。

就是试着u***h_ep_bulk_transfer(class->bulkout发了一个DHCP Discover数据包出去。
然后u***h_ep_bulk_async_transfer(bulkin的callback里面就收到一个一样长的数据包。
我凭经验感觉这就是DHCP Offer,直呼太行了,这就通了。

疯狂调试并对接相关API

有了基本通信能力后,开始整理代码,对接驱动。然后发现这收到的数据包和我发出去的完全一样。。
这不可能是DHCP Offer,看源和目标MAC地址就知道这不对,因为没有硬件分析仪,这里就假定这是设备发出的包。

于是脑补成这是网卡里面可能有类似交换机的机制,因为DHCP Discover是个广播包。

虽然这挺奇怪的,会有回环风险,但host这边并不会转发,所以回环不了。
等把驱动接口对得差不多了,通过软件dump发现所有网卡发出的数据包,根本就没有我想要的,基本都是我自己发出去的,有时连回弹也没有。

分析下来,应该是有些初始化和设置没有做。

于是逐步对接一些接口

rndis_init
发送RNDIS_MSG_INIT,用于初始化

rndis_query_oid
发送RNDIS_MSG_QUERY,查询设备的一些属性,调试下来感觉主要是MAC地址,其它参数在跑通阶段可以不用太关心。

不过RNDIS_OID_GEN_MEDIA_CONNECT_STATUS要关注下,这是反应网线连接状态。

4G网卡并没有网线,因此主要反应SIM卡和网络服务的状态。

rndis_msg_set
发送RNDIS_MSG_SET,设置设备的一些属性,主要是包过滤器。

rndis_keepalive
发送RNDIS_MSG_KEEPALIVE保活,用于在没有数据包时让USB一直有通信。

发RNDIS_MSG_KEEPALIVE时,有时会收到RNDIS_MSG_INDICATE。
此时应该再收1次RNDIS_MSG_KEEPALIVE_C。

开始不通时,以为这里是 关键,一直要等到INDICATE才行,后面换了一个android手机来测试。

发现手机根本就不发INDICATE,通过抓包发现PC在没有INDICATE时就已经在通信了,看来只需要RNDIS_OID_GEN_MEDIA_CONNECT_STATUS显示连接上就能收发数据了。

然而此时host上面的rndis网卡依然无法收到数据,甚至连有没有发出去都开始怀疑了,调试一度陷入困境,好在只是抽空研究一下,并非主要工作。

发现线索

在多次高度中,发现有时 callback中收到的数据,并不一定是我发出的。
有好几次都显示收到一串数据

00000000:  0D 0A 53 4D 53 20 52 45   41 44 59 0D 0A           ..SMS READY..

看数据内容,绝对不是我发出的,且不可能是脏数据,那么至少说明这是网卡发出的。

另外看前面都有
,看起来是个文本交互。

看RNDIS的数据报头,都是二进制的结构体struct rndis_data_hdr
也不可能是这个文本啊,很是奇怪。

直到向大佬请教此问题时,说这个像是AT数据。

AT AT AT !!!

突然想起,这个网卡不就是有3个AT用的串口嘛?那应该是那边的数据,但我并没有读那几个intf啊。

像是错位了。。。

突然想到前面注册class时进行了非常规操作,然后抄过来的cdc代码中是用的[intf + 1],
用于intf[0]里面绑定intf[1]。

而我是自作聪明的写了2个class driver,那此第2个就不能用[intf + 1]。
不然往后挪1个,不正好是AT串口嘛。

把这改回,果然收到了网卡发出的数据。

至此,数据收发都通了,接下来就愉快写重构代码,整理驱动,优化性能并压测稳定性了!!
这种1个Control interface再加1个Data interface基本是标配,这块之前不了解,所以掉坑了!多沉下心来阅读理解规范就能少些弯路!

更多回帖

发帖
×
20
完善资料,
赚取积分