高通SDX62平台 MBIM搜网、查询信号等功能异常
1. 问题描述
按照高通SDX62平台产品规格,其支持RMNET、ECM、RNDIS、PPP、MBIM等拨号;但经测试,发现MBIM拨号功能正常,但搜网、查询信号等功能均异常,返回“error:operation failed:Failure”或返回信息为空
2. 分析与调试
2.1 前期准备
在Linux上进行mbim业务,需要安装MBIM依赖环境:
安装mbim库:apt install libmbim-utils
Mbimcli库版本与ubuntu版本对应关系如下:
Ubuntu 16.04…………mbimcli 1.14
Ubuntu 18.04…………mbimcli 1.18
Ubuntu 20.04…………mbimcli 1.22
版本越高,功能越全,安装完成后,可以使用mbimcli –help 命令查看当前版本支持的mbim命令。
2.2 初步分析
由于mbim查询信号命令在高版本libmbim库中才支持,因此在本地ubuntu20.04复现问题,并抓取log。初步分析模块侧qbi log,发现mbim的扫网命令已成功发送到模块内qbi,qbi已将对应请求通过qmi消息转发给modem进行处理,而modem返回错误码94 (QMI_ERR_NOT_SUPPORTED),log如下:
1980-01-06 00:01:37:168606::framework/src/qbi_qmi_txn.c::qbi_qmi_txn_alloc::0177:::Allocated new QMI transaction for svc_id 1 msg_id 0x0021 req size 232 rsp size 18040 parent txn iid 49
1980-01-06 00:01:37:168684::framework/src/qbi_txn.c::qbi_txn_set_timeout::1484:::Setting timeout in 49 ms for txn iid 600000
1980-01-06 00:01:37:168751::framework/src/qbi_svc.c::qbi_svc_proc_action::3012:::Processing action 1 for txn iid 49
1980-01-06 00:01:37:168814::framework/src/qbi_qmi.c::qbi_qmi_dispatch::2793:::Dispatching QMI requests for QBI transaction iid 49
1980-01-06 00:01:37:169066::framework/src/qbi_qmi.c::qbi_qmi_dispatch::2840:::Sent QMI request for svc_id 1 msg_id 0x0021 with txn iid 49
1980-01-06 00:01:37:169158::framework/src/qbi_txn.c::qbi_txn_check_timeout::0627:::Next transaction times out in 0 ms (ctx id 600000)
1980-01-06 00:01:37:169282::platform/src/qbi_os_linux.c::qbi_os_timer_wake_lock::1325:::Set wake lock
1980-01-06 00:01:37:171003::framework/src/qbi_task.c::qbi_task_cmd_proc_all::0261:::Processing command ID 1
1980-01-06 00:01:37:171146::framework/src/qbi_qmi.c::qbi_qmi_proc_rsp_cb::2027:::Processing QMI response for svc_id 1 msg_id 0x0021 with txn iid 49
1980-01-06 00:01:37:171238::svc/src/qbi_svc_bc_nas.c::qbi_svc_bc_nas_visible_providers_q_nas21_rsp_cb::2511::Error:Received error code 94 from QMI
涉及到qmi返回信息错误,需进一步去排查问题根因。
2.3 高通mbim架构
高通QTI支持MBIM,主要是通过改变现有的软件层——增加一个新的层,QBI,来处理MBIM控制通道协议 。其基本架构如上图:
控制通道:USB/MBIM驱动<=> QBI <=> QMI/Modem
数据通道:USB <=> MBIM-NTB<=> RmNet/Modem
1、QBI是一个新的软件层,包含了特定于处理命令(cid)的逻辑,这些命令在MBIM中定义,通过控制通道作为封装的消息发送。 QBI运行在与USB驱动程序相同的处理器上,并通过QMI与调制解调器进行接口。 它转换用于与主机通信的MBIM cid和用于控制调制解调器的QMI消息。
2、公共消息传递模块是第一个与主机传入的CID请求接触的框架模块。 它解析和验证传入命令的公共部分,将其封送为更易于访问的内部格式,并将请求传递给公共设备服务层以进行分派。 在输出方向上,这一层在内部格式和CID线格式之间转换。
3、CID交互是QBI的重要组成部分。 在接收到新的CID请求后,公共消息传递层在继续发送请求之前调用事务分配例程。
4、公共设备服务层是设备服务实现和QBI框架其余部分之间的主要接口。 设备服务在启动时向公共层注册一次。
通过高通mbim架构架构我们可以看到高通整个mbim消息会在qbi层转换成qmi发送给modem,因此我们进一步梳理消息处理流程,流程总体可分为两部分——mbim消息在qbi侧处理、qmi消息在modem侧处理。
2.4 MBIM消息在qbi侧处理流程简析
当host发送mbim命令如搜网请求mbimcli -p -d /dev/cdc-wdm0 --query-visible-providers,libmbim库会将该命令转换成符合mbim协议的mbim命令MBIM_CID_VISIBLE_PROVIDERS,并将该命令通过模块的mbim口发送给模块,当模块收到该命令后会查找hdlr表,查看对应的处理函数:
通常mbim请求包括两种——查询类、设置类,因此在该hdlr表中会存储查询类型处理函数、设置类型处理函数:
/*! @brief CID-specific handlers for each command type */ typedef struct {
qbi_svc_cmd_hdlr_f *query_fcn; /*!< Handler for QBI_MSG_CMD_TYPE_QUERY */
/*! Minimum size of the InformationBuffer in a valid query request. The framework will reject requests that do not meet this minimum. */
uint32 query_infobuf_min_size;
qbi_svc_cmd_hdlr_f *set_fcn; /*!< Handler for QBI_MSG_CMD_TYPE_SET */
/*! Minimum size of the InformationBuffer in a valid set request. The framework will reject requests that do not meet this minimum. */
uint32 set_infobuf_min_size;
} qbi_svc_cmd_hdlr_tbl_entry_s;
由于扫网请求属于查询命令,不存在设置情况,因此我们可以在SDX62代码中看到MBIM_CID_VISIBLE_PROVIDERS对应的处理函数仅有查询类型一种——qbi_svc_bc_ nas_visible_providers_q_req,而网络注册既可以查询注网情况,也可设置手动注网,因此MBIM_CID_REGISTER_STATE对应的处理函数包括查询和设置两种——qbi_svc_bc _nas_register_state_q_req和qbi_svc_bc_nas_register_state_s_req:
进一步分析扫网请求的处理函数qbi_svc_bc_nas_visible_providers_q_req,在这个函数中首先会判断radio状态的合法性、sim卡状态,只有sim卡状态ready,radio在on的时候才能正常网络搜索和注册;若上述条件符合,进一步确认搜网请求是全扫还是快扫,全扫搜索所有频段,并不断输出