在 Raspberry Pi 上使用 4G LTE 无线调制解调器
对于最近的一个项目,我需要将蜂窝网络连接添加到 Raspberry Pi(实际上是整个集群......但这是未来的故事!)。
我想我会在这篇博文中记录这个过程,这样追随我脚步的人就不需要花太多时间研究了。这篇文章是 40 多个小时的阅读、测试和令人头疼的结果。
对于“4G LTE 和 Linux”似乎没有任何好的中央资源,只有 1000 篇关于 ABC 的关于通过 4G 调制解调器获得互联网连接的帖子——但很少解释它为什么或如何工作. (或者为什么有人应该关心诸如 PPP、ECM、QMI 或 MBIM 之类的随机术语,或者为什么有人会选择qmi_wwan
over cdc_ether
,或者......我可以继续)。
希望你能从我的笔记中学到一些东西。或者指出我明显错误的地方:)
硬件
硬件要求还不错,而且非常实惠。你需要:
Raspberry Pi(几乎任何人都可以,不过我使用了 Raspberry Pi 4(带有 USB 适配器)和 Compute Module 4(带有带有 mini PCIe 插槽的载板)。
迷你 PCI Express 4G LTE 调制解调器。我使用了Quectel EC25-A,但也有一些来自 Sierra Wireless 的我也听说过推荐。
(如果不使用 CM4 + LTE 载板)带有内置 SIM 托盘的 USB 转 mini PCIe 适配器。我使用了 Timack 的这个,但任何人都应该这样做——只要确保它有一个内置的 SIM 卡试试!甚至还有像这样的 Pi HAT将调制解调器硬件直接放置在 Pi 之上。
带有 4G 数据计划的 SIM 卡。我买了一个SixFab SIM并使用他们的按月付费服务进行测试。您可以从手机中取出 SIM 卡(至少在大多数运营商上),但这有点不方便,因为在您将 SIM 卡放回原位之前,您的手机无法获得服务。您也可以从任何主要的公司获得计划和 SIM 卡运营商(例如美国的 AT&T、T-Mobile、Verizon)——尽管您必须确保您使用的运营商与您拥有的 LTE 调制解调器兼容!
天线——大多数调制解调器都有用于 LTE 主、LTE 分集和 GPS/GNSS 的插头。我通常会在紧要关头使用这款 Pulse Electronics U.FL 天线,但有许多选项可以满足不同的需求(例如室外天线、带有更长电缆的天线和SMA 到 U.FL 适配器)——你必须根据具体情况确定你需要什么在你的环境中。
(取决于 SIM 卡)如果您想使用手机中的 SIM 卡(可能是 nano SIM 卡),您还应该准备一个便宜的 SIM 适配器,就像我使用的那样。
为了节省成本,我在 eBay 上买了大部分我用过的东西,价格比在 Amazon 或 SixFab 的商店买新的便宜 30-50%。由于有很多企业部署使用这种类型的设备,所以二手市场上有很多库存。只知道其中一些非常破旧 - 所以只能从信誉良好的供应商那里购买!
注意:本文中的所有说明均假设您在美国。如果您在另一个国家/地区,有些事情需要改变——例如,移远通信调制解调器针对不同的地理区域有不同的品种,例如欧洲、非洲和亚洲部分地区的 EC25-E。
一切就绪后,将 SIM 卡插入 USB 适配器或 CM4 载板上的 SIM 卡托盘,将 LTE 调制解调器安装在 Mini PCIe 插槽中。如果您有 USB 适配器,请将 USB 适配器插入 Pi 的 USB 端口之一——哪个端口并不重要,因为所有这些设备都通过 USB 2.0 (480 Mbps) 运行。
数据计划
在开始设置过程之前,我想我会记下一些关于数据计划的注释,因为至少在我所在的美国地区,很难以合理的价格找到具有静态 IP 地址等功能的大量数据包。
仅作为一个估计点,10 GB 数据的成本约为 30 美元(如果预先购买),我可以找到一些计划,以每月 60-90 美元的价格提供 30-50 GB/月。
我曾经有一个来自 AT&T 的无限制计划,但是一旦你超过某个上限(降至 100 Kbps,这令人痛苦),他们就会严重限制数据,所以几年前我切换到了 30 GB/月的共享计划。
我还研究了获取静态公共 IPv4 地址,但对于我检查过的运营商来说,这太贵了。相反,您可能能够获得一个可路由的 IPv6 地址——一些运营商支持这一点,并且一些网络配置可以使用它。但是 YMMV,你应该准备好处理 CG-NAT。
警告:如果您将 Pi 设置为网络服务器或其他类型的不断使用数据的服务器,请小心——如果您不小心,最终可能会收取巨额超额费用。
Pi 设置
这些调制解调器在 Linux 中得到广泛支持,甚至在 Raspberry Pi OS(基于 Debian)中也得到广泛支持。
由于我使用的是 SixFab SIM,因此我必须登录到我的 SixFab 帐户并将 SIM 设置为“活动”,然后才能连接到 AT&T 的网络。
启动 Raspberry Pi 后,在终端窗口中输入,lsusb
您应该会看到如下内容:
pi@lte:~ $ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 003: ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub pi@lte:~ $ lsusb -t ... /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 2: Dev 3, If 4, Class=Vendor Specific Class, Driver=qmi_wwan, 480M
如果你没有看到输出中列出的调制解调器,你可能没有完全插入它,或者你的 USB 适配器或 CM4 载板没有正确路由 USB 信号(我遇到了一些损坏的实现,所以这不是不可能的)。
如果您使用 来检查内核日志dmesg
,您可能还会看到来自 的一些消息qmi_wwan
,例如:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan
一个设备被列为cdc-wdm0
:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm0
可能不明显——因为这些 4G 调制解调器在物理上采用 mini PCIe 卡形式——它们不会显示为 PCI Express 设备(即使在 Compute Module 4 板上)。它们显示为 USB 设备。
无论如何,该卡应该自动显示为wwan
网络接口,通常wwan0
:
pi@lte:~ $ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 ... 3: wwan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000 link/ether 02:5c:84:4e:14:51 brd ff:ff:ff:ff:ff:ff inet 169.254.231.106/16 brd 169.254.255.255 scope global noprefixroute wwan0 valid_lft forever preferred_lft forever inet6 fe80::8284:d6cd:67d2:ca3a/64 scope link valid_lft forever preferred_lft forever
您可以尝试使用已经使用的此接口ping
,但由于尚未配置,它很可能无法正常工作:
pi@lte:~ $ ping -I wwan0 www.google.com -c 5 PING www.google.com (142.251.32.4) from 169.254.231.106 wwan0: 56(84) bytes of data. --- www.google.com ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4085ms
此时,您需要做出决定——您是否要使用该设备
QMI 模式设置(如wwan0
)
关于这些调制解调器的 QMI、MBIM 和 PPP 模式的关系,有一段较长的历史,我不知道我是否有时间进入这里。但总的来说,您应该使用像我在 QMI 或 ECM 模式下使用的 Quectel 这样的调制解调器。
默认情况下,我购买的所有调制解调器似乎都处于 PPP/QMI 模式(usbmode
返回0
——稍后会详细介绍)。这似乎自动使设备使用qmi_wwan
驱动程序并公开一个wwan0
接口。
SixFab 有一个很好的入门指南:使用 libqmi 通过 QMI 接口设置数据连接。
您需要安装一些实用程序才能通过 QMI 与调制解调器交互:
pi@lte:~ $ sudo apt update && sudo apt install libqmi-utils udhcpc
然后检查调制解调器的当前操作模式:
pi@lte:~ $ sudo qmicli -d /dev/cdc-wdm0 --dms-get-operating-mode [/dev/cdc-wdm0] Operating mode retrieved: Mode: 'online' HW restricted: 'no'
注意:如果稍后返回
Resource temporarily unavailable
错误,您可能需要先停止 ModemManager(如果它已安装并正在运行)sudo systemctl stop ModemManager
,然后再试一次。
如果它没有返回online
,请运行sudo qmicli -d /dev/cdc-wdm0 --dms-set-operating-mode='online'
以将其设置为在线。
然后将界面设置为raw_ip
模式:
pi@lte:~ $ sudo ip link set wwan0 down pi@lte:~ $ echo 'Y' | sudo tee /sys/class/net/wwan0/qmi/raw_ip Y pi@lte:~ $ sudo ip link set wwan0 up
raw-ip
使用以下命令确认它处于模式:
pi@lte:~ $ sudo qmicli -d /dev/cdc-wdm0 --wda-get-data-format [/dev/cdc-wdm0] Successfully got data format QoS flow header: no Link layer protocol: 'raw-ip' ...
现在终于可以连接到您的 SIM 卡所属的网络了!您需要知道网络的 APN——在我的例子中,我使用super
的是 SixFab 卡,但对于 AT&T SIM 来说,我在 iPhone 中使用的一个常见的是nxtgenphone
. Cradlepoint按运营商维护一个常见 APN 列表,但要知道它应该是什么,最简单的方法是询问您的提供商。
运行以下命令进行连接:
pi@lte:~ $ sudo qmicli -p -d /dev/cdc-wdm0 --device-open-net='net-raw-ip|net-no-qos-header' --wds-start-network="apn='YOUR_APN',ip-type=4" --client-no-release-cid [/dev/cdc-wdm0] Network started Packet data handle: '2267587312' [/dev/cdc-wdm0] Client ID not released: Service: 'wds' CID: '19'
注意:如果您有用户名和密码,可以在 apn 后面添加,例如
apn='YOUR_APN',username='YOUR_USERNAME',password='YOUR_PASSWORD',ip-type=4
.
现在,配置udhcpc
为分配默认 IP 地址和路由:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan0
此时,如果您使用ip a
,您应该会看到调制解调器的新设置:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan1
而且,如果一切正常,您应该会看到一些成功的 ping:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan2
耶!但是一旦你重新启动 Pi,网络连接就会丢失。
重新启动后,您必须重新运行以下命令才能再次连接:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan3
即使sudo qmicli -d /dev/cdc-wdm0 --wda-get-data-format
显示它处于raw-ip
模式,似乎您仍然需要停止接口,强制raw_ip
并启动接口,然后您可以连接并设置 IP 和路由udhcpc
。
自动重新连接
设置自动重新连接的最简单方法是在wwan0
接口的新文件中添加以下内容:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan4
注意:如果您的 SIM 计划需要,请务必包括前面所述的用户名和密码。
重新启动 ( sudo reboot
) 并重新启动后,运行以下命令来管理连接:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan5
wwan0
并检查是否有通过with的路由route -n
(或尝试通过接口 ping)。
如果您希望界面在系统启动时出现,请在文件中的行auto wwan0
上方添加以下行:iface
/etc/network/interfaces.d/wwan0
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan6
现在重新启动后,界面应该会自动出现,而不是需要手动sudo ifup wwan0
.
其他有用的 QMI 调制解调器命令
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan7
ECM 模式设置 ( usb0
)
SixFab 有一个很好的指南,用于将调制解调器设置为 ECM 模式,它公开了usb0
网络接口而不是wwan0
接口。
假设您完成了所有 QMI 模式设置,首先确保接口已关闭,使用sudo ifdown wwan0
. 还要注释掉/etc/network/interfaces.d/wwan0
(或删除该文件)中的所有行。
要切换到 ECM 模式,您需要使用minicom
调制解调器通过其串行端口进行通信:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan8
这应该打开一个串行连接。输入AT
并按“Enter”,您应该会看到OK
. 我们将与调制解调器讨论老式 AT 命令,第一个是检查电流的命令usbmode
:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan9
这可能会返回+QCFG: "usbnet",0
,但我们需要将其设置为1
(ECM 模式),因此输入以下命令:
pi@lte:~ $ dmesg | grep qmi [ 5.701450] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device [ 5.703022] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-0000:01:00.0-1.2, WWAN/QMI device, 02:5c:84:4e:14:51 [ 5.703245] usbcore: registered new interface driver qmi_wwan9,1
调制解调器可能会自动重启,但如果没有,请输入以下命令强制重启:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm01
看,很有趣!
大约 5 秒后,您会看到 minicom 中弹出一个警告,例如Cannot open /dev/ttyUSB2!
. 它会消失,随着调制解调器完成其启动过程,您将开始看到更多信息。
一旦您可以AT
再次键入并获取OK
,就该确保 APN 正确无误了。输入以下命令(但请确保为您的 SIM 输入正确的 APN...):
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm02
最后,再次重新启动调制解调器:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm01
等待调制解调器重新启动,然后退出 minicom:按 Ctrl-A,然后按 Z,出现 minicom 的帮助。按 X 离开 minicom 并按 Enter 确认您要离开它。
现在重新启动 Raspberry Pi ( sudo reboot
),然后检查您是否在usb0
接口上获得了 IP 地址:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm04
并确认调制解调器正在使用cdc_ether
驱动程序而不是qmi_wwan
:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm05
测试是否可以通过usb0
接口上网:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm06
万岁!这个设置最好的地方是它似乎在重新启动后自动出现 - 不需要任何网络接口或qmicli
恶作剧。
您仍然可以usb0
使用以下方法禁用接口:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm07
其他有用的 AT 命令
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm08
内置AP配置
usb0
使用该接口的另一个副作用似乎是调制解调器本身是所有管理发生的地方,至少在我的 Quectel 调制解调器上,如果你在路由器中打开网关 IP 地址(例如https://192.168.225.1/
),绕过证书警告,你最终会带有一个小的“Qualcomm MobileAP”登录页面,例如:
注意:由于我是无头操作 Pi,并且几乎不可能通过它浏览页面,因此我使用
curl
SSH隧道(然后我可以在我的 Mac 浏览器(在本例中为 Chrome)中访问调制解调器的 IP 地址。ssh -D 8080 pi@lte.local
localhost
8080
UI 看起来很古老(和许多古老的设计一样,很可能容易受到多种攻击),但它似乎确实有许多设置,如内置防火墙、一些 DHCP 选项和基本的 WWAN 设置:
不过,这不是一个非常直观的 UI——而且我也没有看到任何简单的方法来进行“恢复出厂设置”或从 MobileAP 界面中升级调制解调器。看到 2014 年的版权并没有激发很大的信心:P
更新固件
但是说到调制解调器的固件,它必须有一种方法可以更新,对吧?嗯...有一个名为 QFlash 的工具,我在 SixFab 网站的EC25 页面的“工具”部分找到了该工具。
但它引用的固件文件似乎是凭空变出的,好像是变魔术一样。
我能找到的唯一可供下载的固件文件是通过论坛帖子上的随机 Google Drive 链接或过期的 WeTransfer 链接。是的,就像我会那样做!
如果您搜索 Quectel 的论坛,您会发现类似这样的主题,但似乎永远无法解决:
Quectel 代表:如果您需要最新的固件,您可以发邮件到support@quectel.com来获取,您可以提供您现在使用的固件,然后我们会安排当地的FAE来支持您,他们会帮助提供最新的固件包,升级工具,并指导您如何升级它。谢谢!
客户:本周早些时候,我再次尝试向支持部门请求固件。知道对于典型的固件请求我应该期待什么样的时间吗?
Quectel 代表:请向我们提供您的电子邮件和公司名称,您所在的国家,我们将尽快安排当地的 FAE 为您提供支持。
客户:[循环几次后] ...😑
所以是的......不知道为什么移远通信不能只提供固件下载页面。看起来这不是第一次有人与移远通信碰壁了。我发现Harald Welte 的 OSMOCOM 演示文稿表明很难让 Quectel 为其片上 Linux 构建提供源代码。
选择 QMI 或 ECM
当我开始在 Pi 上了解 4G LTE 的旅程时,我很快就被以下事实弄糊涂了:几乎每个教程和设置指南都有完全不同的说明——有些基本上是复制和粘贴别人的指南。
但似乎没有人谈论过不同的连接方法:为什么存在多种方法?为什么调制解调器(至少 Quectel)带有 QMI 并wwan0
默认设置?一种方法是否比另一种方法更快和/或更受支持?
不知道。
所以我在这个 GitHub 问题中做了一些测试,发现(至少非正式地)我可以使用 ECM 驱动程序(cdc_ether
)获得始终如一的更好的延迟和上传速度。
更重要的是,该驱动程序(设置usb0
接口)似乎与 Linux 中的所有内容开箱即用,不需要我使用一堆额外的命令设置自定义接口文件,并且自动设置就像任何其他网络接口。
我错过了什么吗?qmi_wwan
使用默认 QMI //有什么好处wwan0
吗?
我在 Twitter 上问过这个问题,如果我发现任何结论性的东西,我会更新这篇文章。
选择 Internet 访问的默认接口
使用活动的 4G LTE 接口(无论是wwan0
还是usb0
),可能会出现一个新问题:如果您有两个接口提供 Internet 连接怎么办?例如,如果您的树莓派也有一个 WiFi 或以太网连接,它具有更稳定或更快的互联网,而您只想使用 LTE 连接作为备份呢?
我不会深入讨论,但是您可以通过运行以下命令来了解 Linux 如何优先考虑 Internet 连接的路由route
:
pi@lte:~ $ ls /dev/cdc* /dev/cdc-wdm09
实际上,我写了一篇关于如何更改metric
. 查看该帖子以了解所有详细信息:Raspberry Pi 上的网络接口路由优先级。
但是对于 tl;dr:Linux 将通过具有最低的接口Metric
(在上面的情况下是usb0
)并匹配Gateway
IP 范围(0.0.0.0
基本上意味着“任何 IP 地址”)来路由数据包。
因此,如果您需要管理不同设备的指标优先级,请查看链接的博客文章。
该解决方案不太有用的一种情况是调制解调器处于 QMI 模式 ( wwan0
)。由于这是使用udhcpc
而不是系统的 built-in dhcpcd
,因此设置指标并不像我希望的那样简单。
根据udhcpc 文档,我想我可以添加一个文件/etc/udhcpc/udhcpc.conf
并将其放入IF_METRIC=400
其中,然后将其作为路由指标......但这似乎不起作用。需要更多的调查。
结论
我天真地认为,进入这个项目,4G LTE 连接会相当简单。但事实并非如此。似乎基本上有两层文档:
已经期望专家级理解的数据表和代码注释。
初级指南,例如“如何让您的 Pi 连接到 Internet”
希望我在这里写的一些东西可以弥合这两个层次之间的差距——但我得说实话,当我对这个主题只有部分理解时,我通常不喜欢写博客文章……这就是我所拥有的这里。所以,拿我说的关于 4G LTE 的话加一粒盐;)