1、拨号模式简介
ECM(Ethernet Networking Control Model 以太网控制模型)用于在设备和主机之间传输以太网数据 包。在操作系统看来,CDC ECM 设备就是一个虚拟以太网卡,包含标准网卡需要的 MAC 地址和 IP 地址。 CDC ECM 设备通常是一个以太网卡,用于连接 LAN 或者是 WLAN。当客户主机发起 ECM 拨号的请求时, FG650 相当于一个路由器,模块内部会调用相应的服务实现 WWAN 拨号。在拨号成功后,模块内部会启 动 DHCP server 等功能。客户端应用系统通过 DHCP client 服务,获取模块 DHCP server 分配的 IP。客户 主机调用 DHCP 等脚本实现把模块从网络侧获取到的 IP 和 DNS 配置到本机,实现上网。
NCM (Network Control Model) 是 ECM 协议的改进版。将多个以太网包组成一个 NTB 包在 USB 总线上传输,提高了带宽利用率。
RNDIS(Remote Network Driver Interface Specification), 既是远程网络驱动接口规范, 基于 USB 实 现 RNDIS 实际上就是 TCP/IP over USB,就是在 USB 设备上跑 TCP/IP,让 USB 设备看上去像一块网卡。
2、拨号模式选择
FG650 支持 ECM/NCM/RNDIS 三种模式,三种模式的主要特性如下表:
3、USB端口信息
ECM模式端口枚举顺序
NCM模式端口枚举顺序
RNDIS模式端口枚举顺序
模块的USB支持多种模式,可以向模块发送AT+GTUSBMODE?,查询当前处于什么模式,也 可以用 AT+GTUSBMODE=<mode>,调整 usb 模式,模块回复 OK 后,AT+CFUN=15 重启模组生效。
4、USB枚举模式确认和修改
采用 AT+GTUSBMODE?查询当前 USB 模式。
AT+GTUSBMODE?
+GTUSBMODE: 39
OK
采用 AT+GTUSBMODE= 指令可以修改 USB 模式。
AT+GTUSBMODE?
+GTUSBMODE: 39
OK
AT+GTUSBMODE=37
OK
AT+CFUN=15 //重启模组生效
5、USB 串口驱动添加系统组件
1、内核选中USB driver for GSM and CDMA modems 组件,增加设备支持打开内核源码文件ption.c({kernel/drivers/usb/serial/option.c)。在option_ids数组添加FM650的PID/VID。注意 ECM/NCM/RNDIS 等不同模式下的 PID 是不一样的。需要根据模 组的模式添加相应的 PID/VID(请参考 USB 端口章节),或者可以把 FM650 支持的所有模式 ID 都添加上去。
#define FIBOCOM_VENDOR_ID 0x2CB7
#define FIBOCOM_PRODUCT_FG650_ECM 0x0A04
#define FIBOCOM_PRODUCT_FG650_NCM 0x0A05
#define FIBOCOM_PRODUCT_FG650_RNDIS 0x0A06
static const struct usb_device_id option_ids[] = {
#if 1
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_ECM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_NCM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_RNDIS)},
#endif
2、在 USB 串口驱动中,过滤 ECM/NCM/RNDIS 接口。由于 USB 串口跟 ECM/NCM/RNDIS 都属于 非标准 CDC 设备,需要防止 ECM/NCM/RNDIS 口被 USB 串口驱动加载而导致无法正常加载 ECM/NCM/RNDIS 口驱动。有三种方式可以解决:
A:比较新的 kernel 版本,在 option.c 中的 opiton_ids 添加代码如下:
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_ECM),
.driver_info = RSVD(0) | RSVD(1) | RSVD(5)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_NCM),
.driver_info = RSVD(0) | RSVD(1) | RSVD(6)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_RNDIS),
.driver_info = RSVD(0) | RSVD(1) | RSVD(6)
},
B:比较老的内核,在option_ids[]添加
static const struct usb_device_id option_ids[] = {
#if 1
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_ECM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_NCM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_RNDIS)},
#endif
并在 probe 函数内判断当前的 interface num 进行过滤,具体如下:
#if 1
if (serial->dev->descriptor.idVendor == cpu_to_le16(FIBOCOM_VENDOR_ID) &&
serial->dev->descriptor.idProduct == cpu_to_le16(FIBOCOM_PRODUCT_FG650_ECM) &&
serial->interface->cur_altsetting->desc.bInterfaceNumber <= 1) {
printk(KERN_INFO "Discover the 4th interface for fibocom\n");
return -ENODEV;
}
if (serial->dev->descriptor.idVendor == cpu_to_le16(FIBOCOM_VENDOR_ID) &&
serial->dev->descriptor.idProduct == cpu_to_le16(FIBOCOM_PRODUCT_FG650_NCM) &&
serial->interface->cur_altsetting->desc.bInterfaceNumber <= 1) {
printk(KERN_INFO "Discover the 4th interface for fibocom\n");
return -ENODEV;
}
if (serial->dev->descriptor.idVendor == cpu_to_le16(FIBOCOM_VENDOR_ID) &&
serial->dev->descriptor.idProduct == cpu_to_le16(FIBOCOM_PRODUCT_FG650_RNDIS) &&
serial->interface->cur_altsetting->desc.bInterfaceNumber <= 1) {
printk(KERN_INFO "Discover the 4th interface for fibocom\n");
return -ENODEV;
}
#endif
/* Store the device flags so we can use them during attach. */
usb_set_serial_data(serial, (void *)device_flags);
return 0;
3、USB串口驱动加载确认
执行 lsusb,检查是否检测到模组 USB, 如果找到对应模式的 VID/PID,表示 USB 已正常检测到 再通过 ls /dev/ttyUSB* 检查 USB 串口驱动是否正常加载。
root@OpenWrt:/# lsusb
Bus 002 Device 001: ID 1d6b:0001 Linux 5.4.179 ohci_hcd Generic Platform OHCI controller
Bus 001 Device 003: ID 2cb7:0a06 Fibocom Wireless Inc. FM650 Module
Bus 001 Device 001: ID 1d6b:0002 Linux 5.4.179 ehci_hcd EHCI Host Controller
root@OpenWrt:/#
root@OpenWrt:/# ls /dev/ttyUSB*
/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3
root@OpenWrt:/#
7、内核环境确认
ECM/NCM 是一种标准的设备间以太网帧数据交换协议,系统中需要加载 CDC ETHER 驱动,RNDIS 需要配置 CONFIG_USB_NET_RNDIS_HOST 请参考如下步骤。
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_RNDIS_HOST = y
内驱需要添加如下驱动
如果是 ECM 模式,选择:
CDC Ethernet support(smart devices such as cable modems)
如果是 NCM 模式,选择:
CDC Ethernet support(smart devices such as cable modems)
CDC NCM Support
如果是 RNDIS 模式,选择:
Host for RNDIS and ActiveSync devices
8、拨号流程
9、Openwrt配置
切换USB模式为rndis(其他两种也可以),并确定模块已经获取到IP
T+GTRNDIS? //查询拨号状态,查看模块是否已经获取到 IP。
+GTRNDIS: 1,1,"100.85.126.41","202.101.172.37", "202.101.173.157"
OK
在Luci界面Network->Interfaces->Add New Interface配置如下
设置防火墙为wan