cdc_mbim - 用于 CDC MBIM 移动宽带调制解调器的驱动程序¶
cdc_mbim 驱动程序支持符合“移动宽带接口模型的通用串行总线通信类子类规范”[1] 的 USB 设备,该规范是对“网络控制模型设备的通用串行总线通信类子类规范”[2] 的进一步发展,针对移动宽带设备(也称为“3G/LTE 调制解调器”)进行了优化。
命令行参数¶
cdc_mbim 驱动程序没有自己的参数。但是,对于 NCM 1.0 向后兼容的 MBIM 功能([1] 的第 3.2 节中定义的“NCM/MBIM 功能”)的探测行为,受 cdc_ncm 驱动程序参数的影响
prefer_mbim¶
- 类型:
布尔
- 有效范围:
N/Y (0-1)
- 默认值:
Y(首选 MBIM)
此参数设置 NCM/MBIM 功能的系统策略。此类功能将由 cdc_ncm 驱动程序或 cdc_mbim 驱动程序处理,具体取决于 prefer_mbim 设置。设置 prefer_mbim=N 会使 cdc_mbim 驱动程序忽略这些功能,而让 cdc_ncm 驱动程序来处理它们。
该参数是可写的,并且可以随时更改。需要手动取消绑定/绑定,才能使更改对绑定到“错误”驱动程序的 NCM/MBIM 功能生效
基本用法¶
MBIM 功能在未管理时处于非活动状态。cdc_mbim 驱动程序仅提供到 MBIM 控制通道的用户空间接口,并且不会参与该功能的管理。这意味着始终需要用户空间 MBIM 管理应用程序来启用 MBIM 功能。
此类用户空间应用程序包括但不限于
mbimcli(包含在 libmbim [3] 库中),以及
ModemManager [4]
建立 MBIM IP 会话至少需要管理应用程序执行以下操作
打开控制通道
配置网络连接设置
连接到网络
配置 IP 接口
管理应用程序开发¶
驱动程序 <-> 用户空间接口如下所述。MBIM 控制通道协议在 [1] 中进行了描述。
MBIM 控制通道用户空间 ABI¶
/dev/cdc-wdmX 字符设备¶
该驱动程序使用 cdc-wdm 驱动程序作为子驱动程序,创建到 MBIM 功能控制通道的双向管道。控制通道管道的用户空间端是 /dev/cdc-wdmX 字符设备。
cdc_mbim 驱动程序不处理或管理控制通道上的消息。该通道完全委托给用户空间管理应用程序。因此,此应用程序有责任确保它符合 [1] 中的所有控制通道要求。
cdc-wdmX 设备创建为 MBIM 控制接口 USB 设备的子设备。可以使用 sysfs 查找与特定 MBIM 功能关联的字符设备。例如
bjorn@nemi:~$ ls /sys/bus/usb/drivers/cdc_mbim/2-4:2.12/usbmisc
cdc-wdm0
bjorn@nemi:~$ grep . /sys/bus/usb/drivers/cdc_mbim/2-4:2.12/usbmisc/cdc-wdm0/dev
180:0
USB 配置描述符¶
CDC MBIM 功能描述符的 wMaxControlMessage 字段限制了最大控制消息大小。管理应用程序负责协商符合 [1] 的第 9.3.1 节要求的控制消息大小,同时考虑此描述符字段。
用户空间应用程序可以使用 [6] 或 [7] 中描述的两个 USB 配置描述符内核接口中的任何一个来访问 MBIM 功能的 CDC MBIM 功能描述符。
另请参阅下面的 ioctl 文档。
分片¶
用户空间应用程序负责所有控制消息的分片和去分片,如 [1] 的第 9.5 节中所述。
/dev/cdc-wdmX write()¶
来自管理应用程序的 MBIM 控制消息不得超过协商的控制消息大小。
/dev/cdc-wdmX read()¶
管理应用程序必须接受最大为协商的控制消息大小的控制消息。
/dev/cdc-wdmX ioctl()¶
IOCTL_WDM_MAX_COMMAND:获取最大命令大小 此 ioctl 返回 MBIM 设备的 CDC MBIM 功能描述符的 wMaxControlMessage 字段。这旨在提供方便,从而无需从用户空间解析 USB 描述符。
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/usb/cdc-wdm.h>
int main()
{
__u16 max;
int fd = open("/dev/cdc-wdm0", O_RDWR);
if (!ioctl(fd, IOCTL_WDM_MAX_COMMAND, &max))
printf("wMaxControlMessage is %d\n", max);
}
自定义设备服务¶
MBIM 规范允许供应商自由定义其他服务。cdc_mbim 驱动程序完全支持这一点。
对新 MBIM 服务(包括供应商指定的服务)的支持完全在用户空间中实现,就像 MBIM 控制协议的其余部分一样
新服务应在 MBIM 注册表 [5] 中注册。
MBIM 数据通道用户空间 ABI¶
wwanY 网络设备¶
cdc_mbim 驱动程序将 MBIM 数据通道表示为“wwan”类型的单个网络设备。此网络设备最初映射到 MBIM IP 会话 0。
多路复用 IP 会话 (IPS)¶
MBIM 允许在单个 USB 数据通道上多路复用最多 256 个 IP 会话。cdc_mbim 驱动程序将此类 IP 会话建模为主 wwanY 设备的 802.1q VLAN 子设备,将 MBIM IP 会话 Z 映射到 VLAN ID Z,对于所有大于 0 的 Z 值。
设备最大 Z 值在 [1] 的第 10.5.1 节中描述的 MBIM_DEVICE_CAPS_INFO 结构中给出。
用户空间管理应用程序负责在建立 SessionId 大于 0 的 MBIM IP 会话之前添加新的 VLAN 链接。可以使用常规 VLAN 内核接口(ioctl 或 netlink)添加这些链接。
例如,为 SessionId 为 3 的 MBIM IP 会话添加链接
ip link add link wwan0 name wwan0.3 type vlan id 3
驱动程序会自动将“wwan0.3”网络设备映射到 MBIM IP 会话 3。
设备服务流 (DSS)¶
MBIM 还允许在同一共享 USB 数据通道上多路复用最多 256 个非 IP 数据流。cdc_mbim 驱动程序将这些会话建模为主 wwanY 设备的另一组 802.1q VLAN 子设备,将 MBIM DSS 会话 A 映射到 VLAN ID (256 + A),对于所有 A 值。
设备最大 A 值在 [1] 的第 10.5.29 节中描述的 MBIM_DEVICE_SERVICES_INFO 结构中给出。
DSS VLAN 子设备用作共享 MBIM 数据通道和支持 MBIM DSS 的用户空间应用程序之间的实用接口。它不打算直接呈现给最终用户。假设启动 DSS 会话的用户空间应用程序还会负责对 DSS 数据进行必要的成帧,以适合流类型的方式向最终用户呈现流。
网络设备 ABI 要求为每个正在传输的 DSS 数据帧提供一个虚拟以太网头。此头的内容是任意的,但以下情况例外
使用 IP 协议(0x0800 或 0x86dd)的 TX 帧将被丢弃
RX 帧的协议字段将设置为 ETH_P_802_3(但不会是正确格式化的 802.3 帧)
RX 帧的目的地址将设置为主设备的硬件地址
支持 DSS 的用户空间管理应用程序负责在 TX 上添加虚拟以太网头并在 RX 上剥离它。
这是一个使用常用工具的简单示例,将 DssSessionId 5 导出为 /dev/nmea 符号链接指向的 pty 字符设备
ip link add link wwan0 name wwan0.dss5 type vlan id 261
ip link set dev wwan0.dss5 up
socat INTERFACE:wwan0.dss5,type=2 PTY:,echo=0,link=/dev/nmea
这只是一个示例,最适合用于测试 DSS 服务。支持特定 MBIM DSS 服务用户空间应用程序应使用该服务所需的工具和编程接口。
请注意,为 DSS 会话添加 VLAN 链接是完全可选的。管理应用程序可以选择直接将数据包套接字绑定到主网络设备,使用收到的 VLAN 标签将帧映射到正确的 DSS 会话,并在 TX 上添加带有适当标签的 18 字节 VLAN 以太网头。在这种情况下,建议使用套接字过滤器,仅匹配 DSS VLAN 子集。这样可以避免不必要地将不相关的 IP 会话数据复制到用户空间。例如
static struct sock_filter dssfilter[] = {
/* use special negative offsets to get VLAN tag */
BPF_STMT(BPF_LD|BPF_B|BPF_ABS, SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT),
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 1, 0, 6), /* true */
/* verify DSS VLAN range */
BPF_STMT(BPF_LD|BPF_H|BPF_ABS, SKF_AD_OFF + SKF_AD_VLAN_TAG),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 0, 4), /* 256 is first DSS VLAN */
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 512, 3, 0), /* 511 is last DSS VLAN */
/* verify ethertype */
BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 2 * ETH_ALEN),
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ETH_P_802_3, 0, 1),
BPF_STMT(BPF_RET|BPF_K, (u_int)-1), /* accept */
BPF_STMT(BPF_RET|BPF_K, 0), /* ignore */
};
标记的 IP 会话 0 VLAN¶
如上所述,MBIM IP 会话 0 被驱动程序视为特殊会话。它最初映射到 wwanY 网络设备上的未标记帧。
此映射对多路复用 IPS 和 DSS 会话有一些限制,这些限制可能并不总是实用
没有 IPS 或 DSS 会话可以使用大于 IP 会话 0 上的 MTU 的帧大小
除非表示 IP 会话 0 的网络设备也处于启动状态,否则没有 IPS 或 DSS 会话可以处于启动状态
可以通过选择使驱动程序将 IP 会话 0 映射到 VLAN 子设备(类似于所有其他 IP 会话)来避免这些问题。可以通过为魔术 VLAN ID 4094 添加 VLAN 链接来触发此行为。然后,驱动程序将立即开始将 MBIM IP 会话 0 映射到此 VLAN,并将丢弃主 wwanY 设备上的未标记帧。
提示:将此 VLAN 子设备命名为 MBIM SessionID 而不是 VLAN ID 可能对最终用户来说更不容易混淆。例如
ip link add link wwan0 name wwan0.0 type vlan id 4094
VLAN 映射¶
总结上述 cdc_mbim 驱动程序映射,我们在 wwanY 网络设备上的 VLAN 标签和共享 USB 数据通道上的 MBIM 会话之间有以下关系
VLAN ID MBIM type MBIM SessionID Notes
---------------------------------------------------------
untagged IPS 0 a)
1 - 255 IPS 1 - 255 <VLANID>
256 - 511 DSS 0 - 255 <VLANID - 256>
512 - 4093 b)
4094 IPS 0 c)
a) if no VLAN ID 4094 link exists, else dropped
b) unsupported VLAN range, unconditionally dropped
c) if a VLAN ID 4094 link exists, else dropped
参考文献¶
USB Implementers Forum, Inc. - “移动宽带接口模型的通用串行总线通信类子类规范”,修订版 1.0(勘误表 1),2013 年 5 月 1 日
USB Implementers Forum, Inc. - “网络控制模型设备的通用串行总线通信类子类规范”,修订版 1.0(勘误表 1),2010 年 11 月 24 日
libmbim - “一个基于 glib 的库,用于与使用移动接口宽带模型 (MBIM) 协议的 WWAN 调制解调器和设备通信”
ModemManager - “一个 DBus 激活的守护程序,用于控制移动宽带 (2G/3G/4G) 设备和连接”
“MBIM(移动宽带接口模型)注册表”
“/sys/kernel/debug/usb/devices 输出格式”
“/sys/bus/usb/devices/.../descriptors”
Documentation/ABI/stable/sysfs-bus-usb