0%

USB 通信设备类与 USB Dongle 拨号

  • USB 通信设备类
  • USB Dongle 拨号

Defined Class Codes

Defined Class Codes

例如:

Linux4.9 include/uapi/linux/usb/ch9.h 可以看到各个定义值

Communications Class Subclass Codes

USB 的 CDC 类是 USB 通信设备类(Communication Device Class)的简称。CDC 类是 USB 组织定义的一类专门给各种通信设备(电信通信设备和中速网络通信设备)使用的 USB 子类。

具体列表见文档 Universal Serial Bus Class Definitions for Communications Devices 4.3章节:

  • 00h RESERVED
  • 01h Direct Line Control Model [USBPSTN1.2]
  • 02h Abstract Control Model [USBPSTN1.2]
  • 03h Telephone Control Model [USBPSTN1.2]
  • 04h Multi-Channel Control Model [USBISDN1.2]
  • 05h CAPI Control Model [USBISDN1.2]
  • 06h Ethernet Networking Control Model [USBECM1.2]
  • 07h ATM Networking Control Model [USBATM1.2]
  • 08h Wireless Handset Control Model [USBWMC1.1]
  • 09h Device Management [USBWMC1.1]
  • 0Ah Mobile Direct Line Model [USBWMC1.1]
  • 0Bh OBEX [USBWMC1.1]
  • 0Ch Ethernet Emulation Model [USBEEM1.0]
  • 0Dh Network Control Model [USBNCM1.0]
  • 0Eh Mobile Broadband Interface Model [USBMBIM1.0]
  • 0Dh-7Fh RESERVED (future use)
  • 80-FEh RESERVED (vendor specific)

Linux4.9 内核实现

构造 USB 设备宏定义

/**
 * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces
 * @cl: bInterfaceClass value
 * @sc: bInterfaceSubClass value
 * @pr: bInterfaceProtocol value
 *
 * This macro is used to create a struct usb_device_id that matches a
 * specific class of interfaces.
 */
#define USB_INTERFACE_INFO(cl, sc, pr) \
    .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \
    .bInterfaceClass = (cl), \
    .bInterfaceSubClass = (sc), \
    .bInterfaceProtocol = (pr)

例如:

/* Telit LE922A6 in MBIM composition */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
},

{
    USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM,
            USB_CDC_PROTO_EEM),
    .driver_info = (unsigned long) &eem_info,
},

/* Telit LE910 V2 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x0036,
    USB_CLASS_COMM,
    USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
  .driver_info = (unsigned long)&wwan_noarp_info,
},

内核文件

$ find -name "cdc_*"
./include/linux/usb/cdc_ncm.h
./drivers/net/usb/cdc_mbim.c
./drivers/net/usb/cdc_ncm.c
./drivers/net/usb/cdc_ether.c
./drivers/net/usb/cdc_eem.c
./drivers/net/usb/cdc_ether.o
./drivers/net/usb/cdc_subset.c
./Documentation/networking/cdc_mbim.txt

Rndis

在文件 drivers/net/usb/rndis_host.c 中发现如下代码

static const struct usb_device_id   products [] = {
{
    /* 2Wire HomePortal 1000SW */
    USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
                      USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
    .driver_info = (unsigned long) &rndis_poll_status_info,
}, {
    /* RNDIS is MSFT's un-official variant of CDC ACM */
    USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
    .driver_info = (unsigned long) &rndis_info,
}, {
    /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
    USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
    .driver_info = (unsigned long) &rndis_poll_status_info,
}, {
    /* RNDIS for tethering */
    USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
    .driver_info = (unsigned long) &rndis_info,
},
    { },        // END
};
MODULE_DEVICE_TABLE(usb, products);

RNDIS是一个以太网端口 ( Ethernet port )。最开始是微软控制的,用以取代 CDC Ethernet 的协议。Linux 支持它仅仅是因为微软不支持 CDC以太网标准。

USB Dongle 拨号

Many modern (and most LTE) usb modems provide qmi, mbim, ncm, rndis protocol for connection instead of legacy ppp protocol, they are faster and better, overall recommended. For more information:

内核设备列表

USB 设备需要关心 ProductIDVendorID,用于表示某一种具体的设备,例如文件 unusual_devs.h 列举了非常规设备列表,表示这些设备需要特殊处理

/*
 * Reported by fangxiaozhi <huananhu@huawei.com>
 * This brings the HUAWEI data card devices into multi-port mode
 */
UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000,
        "HUAWEI MOBILE",
        "Mass Storage",
        USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
        0),
UNUSUAL_DEV(  0x12d1, 0x1003, 0x0000, 0x0000,
        "HUAWEI MOBILE",
        "Mass Storage",
        USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
        0),

Add New USB Dongle

在内核中增加普通 USB Dongle 设备,修改 drivers/usb/serial/option.c 中的数组 option_ids

{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1C0B, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1C05, 0xff, 0xff, 0xff) },

Ref

  1. USB中CDC-ECM的了解和配置
  2. RNDIS,ECM及MBIM报文简述
  3. Use 3g/UMTS USB Dongle for WAN connection
  4. What’s different in USB class when the devices are modem?
  5. Linux那些事儿之我是U盘(18)
  6. Android f_rndis 分析笔记
  7. RNDIS原理分析