====== Qualcomm Gobi 1000 modem ====== This device is available under a variety of Vendor names and models - one of the most common appears to be HP / Lenovo UN2400. I bought a couple on eBay as "HP / Dell / Qualcomm T77Z039.04 UMTS" cards for €5 each. If I could get them working, nice; if not, it's only €5. I bought two simply because I have two [[pc_engines_apu_4d4|APU 4D4s]] and I like to keep things consistent. I would expect the process for many other Qualcomm devices to be very similar. Here are some links to the documentation and/or download sites I found which helped me to get these cards working: https://ubuntuforums.org/archive/index.php/t-1008200.html\\ https://thinkwiki.de/Qualcomm_Gobi_2000_unter_Linux_installieren\\ https://drivers.softpedia.com/get/NETWORK-CARD/OTHER-NETWORK-CARDS/HP-Multi-WWAN-Driver-Installer-100.shtml\\ https://github.com/kicer/gobi_loader\\ https://github.com/kicer/gobi_loader/blob/master/60-gobi.rules\\ https://techship.com/faq/how-to-step-by-step-set-up-a-data-connection-over-qmi-interface-using-qmicli-and-in-kernel-driver-qmi-wwan-in-linux/\\ Note that the low price reflects the device's age and capabilities - these things are UMTS modems. Once I got mine working as described here, I ended up with about 8 kilobytes per second downstream, and I **think** about the same upstream (although see Problem below regarding upstream data transfers). It's good enough for an emergency SSH session, which is my primary purpose, but you're not going to use this for a permanent Internet link. ===== Plug in the card ===== I plugged the card into slot J14 (the middle mini PCIe connector) - this supports the USB interface needed for the Gobi 1000. The SIM card slot for J14 is the one nearest to the board mounting hole (on the underside of the PCB), and the SIM card goes in with the contacts facing up (ie: towards the PCB) and with the notch-end first. The socket has a latching mechanism which should click and hold the card in place until you push the card slightly in again. After powering on the APU and booting into Linux I could then see in **dmesg**: usbserial: USB Serial support registered for Qualcomm USB modem qcserial 3-1.3:1.0: Qualcomm USB modem converter detected usb 3-1.3: Qualcomm USB modem converter now attached to ttyUSB0 **lsusb** showed this new USB device: # lsusb Bus 001 Device 003: ID 03f0:201d HP, Inc un2400 Gobi Wireless Modem (QDL mode) Bus 001 Device 002: ID 0438:7900 Advanced Micro Devices, Inc. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub As you can see, the modem is detected, and is in "QDL" mode, meaning it's ready to download Qualcomm firmware (without which it does nothing useful). ===== Getting the firmware ===== This is the tricky part. For whatever reason, Qualcomm happily sells hardware but does not make the firmware to use it available for download. They seem to assume that anyone using one of these cards will be doing so: * in a laptop * running MS Windows * from a vendor who also supplies drivers for the card So, if you're using this in a router running Linux, none of the above apply. You should be able to obtain the firmware using one or other of the links I've put at the top of this page. I managed to download a driver from https://support.lenovo.com/us/en/downloads/ds001302 and when run under Wine it expanded to provide me with a .msi file but I was unsuccessful in extracting anything from this. I then managed to find and download http://ftp.hp.com/pub/softpaq/sp42501-43000/sp42869.exe which when run under Wine gave me (amongst a load of other Windows stuff) a directory tree SWSetup/SP42869/QCImages/Source/Packages containing 11 numbered directories, each containing different versions of **amss.mbn** and **apps.mbn** files. The numbered directories apparently correspond to different mobile service providers, so I used the files from directory number 6, which is "generic". These later turned out to work (with a UK Tesco SIM card roaming on the German T-Mobile network, and also with a UK Lebara SIM card on both the UK Vodafone and roaming on the German Vodafone networks, incidentally). I did not spend any time wondering what the difference between firmware drivers associated with different mobile network providers might be. ===== Loading the firmware ===== Put the firmware files **amss.mbn** and **apps.mbn** into **/lib/firmware/gobi** and install the package **gobi-loader** This package should apparently include a file **/etc/udev/rules.d/60-gobi.rules** For some reason this didn't get installed on my system, so I fetched it from [[https://github.com/kicer/gobi_loader/raw/master/60-gobi.rules|git]] and put it in place manually. After rebooting the machine (I think a hardware power cycle may be necessary, but I haven't researched this fully; I did it anyway) the firmware should get loaded during module setup, and now **lsusb** will show you: # lsusb Bus 003 Device 004: ID 03f0:1f1d HP, Inc un2400 Gobi Wireless Modem Bus 003 Device 002: ID 0438:7900 Advanced Micro Devices, Inc. Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Note that the vendor ID **03f0** remains the same but the device ID which was **201d** is now **1f1d**, and it is no longer labelled as being in "QDL mode". You should also now see in dmesg: usb 3-1.3: USB disconnect, device number 3 qcserial ttyUSB0: Qualcomm USB modem converter now disconnected from ttyUSB0 qcserial 3-1.3:1.0: device disconnected usb 3-1.3: new high-speed USB device number 4 using ehci-pci usb 3-1.3: New USB device found, idVendor=03f0, idProduct=1f1d, bcdDevice= 0.01 usb 3-1.3: New USB device strings: Mfr=2, Product=1, SerialNumber=0 usb 3-1.3: Product: HP un2400 Mobile Broadband Module usb 3-1.3: Manufacturer: HP un2400 Mobile Broadband Module qcserial 3-1.3:1.0: Qualcomm USB modem converter detected usb 3-1.3: Qualcomm USB modem converter now attached to ttyUSB0 qcserial 3-1.3:1.2: Qualcomm USB modem converter detected usb 3-1.3: Qualcomm USB modem converter now attached to ttyUSB1 usbcore: registered new interface driver cdc_wdm qmi_wwan 3-1.3:1.3: cdc-wdm0: USB WDM device qmi_wwan 3-1.3:1.3 wwan0: register 'qmi_wwan' at usb-0000:00:13.0-1.3, WWAN/QMI device, 52:c4:8c:04:f0:5d ===== Talking to the modem ===== At this point you now have __two__ devices **/dev/ttyUSB0** and **/dev/ttyUSB1** and you can talk to the second one using a terminal emulator such as minicom: # minicom -D /dev/ttyUSB1 Welcome to minicom 2.8 OPTIONS: I18n Port /dev/ttyUSB1, 11:56:48 Press CTRL-A Z for help on special keys ATI Manufacturer: QUALCOMM INCORPORATED Model: 88 Revision: D1020-SUUAASGA-4352 1 [Apr 14 2008 19:00:00] IMEI: 980049001741249 +GCAP: +CGSM,+DS OK(Press **Ctrl-A Q Enter** to exit.) Other **AT** commands you might find useful (also see links below for more): | **AT+COPS?** | Show current mode, network operator and access technology | | | +COPS: 0,0,"T-Mobile D",0 means T-Mobile D (ie: Germany) using GSM | | **AT+CNUM** | Show the mobile phone number from the SIM card (doesn't necessarily work) | | **AT+CCID** | Show the integrated circuit card identifier from the SIM card | | **AT+CREG?** | Show network registration status | | | +CREG: 0,1 means registered on the home network | | | +CREG: 0,2 means not registered but searching | | | +CREG: 0,3 means registration denied | | | +CREG: 0,4 means unknown, perhaps out of coverage | | | +CREG: 0,5 means registered on a roaming network | | **AT+CSQ** | Show signal quality | | | +CSQ: 8,99 means Signal strength 8 (not too bad), error rate undetectable | ===== Turning it into a network interface ===== Install the **libqmi-utils** package and see what it will tell you about the card: # qmicli --device=/dev/cdc-wdm0 --device-open-proxy --dms-get-ids [/dev/cdc-wdm0] Device IDs retrieved: ESN: '802F8A66' IMEI: '980049001741249' MEID: 'A10000109F8D7A' Check which data format the card is going to use: # qmicli --device=/dev/cdc-wdm0 --get-expected-data-format 802-3 If you want to switch from 802-3 mode to raw-ip mode: # ip link set dev wwan0 down # echo Y > /sys/class/net/wwan0/qmi/raw_ip # ip link set dev wwan0 up # qmicli --device=/dev/cdc-wdm0 --get-expected-data-format raw-ip If you use the device in raw IP mode, you need a DHCP client which can understand this type of interface. ISC's dhcpc doesn't, so the best bet is to install the **udhcpc** package and use that. If you use the device in 802.3 mode, ISC's dhcpc works fine. The following worked for me to get data connectivity (this was documented from the very first time I got it working, so the following commands can probably be improved upon):# qmi-network /dev/cdc-wdm0 start Profile at '/etc/qmi-network.conf' not found... Checking data format with 'qmicli -d /dev/cdc-wdm0 --wda-get-data-format '... error: couldn't create client for the 'wda' service: QMI protocol error (31): 'InvalidServiceType' Device link layer protocol not retrieved: WDA unsupported Starting network with 'qmicli -d /dev/cdc-wdm0 --wds-start-network= --client-no-release-cid '... Saving state at /tmp/qmi-network-state-cdc-wdm0... (CID: 15) Saving state at /tmp/qmi-network-state-cdc-wdm0... (PDH: 31067528) Network started successfully # udhcpc -q -f -n -i wwan0 udhcpc: started, v1.30.1 udhcpc: sending discover udhcpc: sending select for 10.141.147.3 udhcpc: lease of 10.141.147.3 obtained, lease time 7200 ip: RTNETLINK answers: File exists # ifconfig wwan0 wwan0: flags=4163 mtu 1500 inet 10.141.147.3 netmask 255.255.255.248 broadcast 10.141.147.7 inet6 fe80::5019:5dff:fed2:9d8 prefixlen 64 scopeid 0x20 ether 52:19:5d:d2:09:d8 txqueuelen 1000 (Ethernet) RX packets 2 bytes 612 (612.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 9 bytes 1430 (1.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10.141.147.0 0.0.0.0 255.255.255.248 U 0 0 0 wwan0 # route add 8.8.8.8 dev wwan0 # ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=114 time=1977 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=114 time=1037 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=114 time=457 ms 64 bytes from 8.8.8.8: icmp_seq=4 ttl=114 time=220 ms 64 bytes from 8.8.8.8: icmp_seq=5 ttl=114 time=156 ms 64 bytes from 8.8.8.8: icmp_seq=6 ttl=114 time=137 ms 64 bytes from 8.8.8.8: icmp_seq=7 ttl=114 time=156 ms ^C --- 8.8.8.8 ping statistics --- 7 packets transmitted, 7 received, 0% packet loss, time 6004ms rtt min/avg/max/mdev = 137.465/591.270/1977.211/639.323 ms, pipe 2 # route del 8.8.8.8 dev wwan0 # qmi-network /dev/cdc-wdm0 stop Profile at '/etc/qmi-network.conf' not found... Loading previous state from /tmp/qmi-network-state-cdc-wdm0... Previous CID: 15 Previous PDH: 31067528 Stopping network with 'qmicli -d /dev/cdc-wdm0 --wds-stop-network=31067528 --client-cid=15 '... Network stopped successfully Clearing state at /tmp/qmi-network-state-cdc-wdm0... If you want to use 802.3 mode instead of raw-ip, the commands above are identical except that instead of **udhcpc -q -f -n -i wwan0** you would use **dhclient wwan0**. I do this to keep my /etc/network/interfaces file simpler. Note that the ping round-trip times should be **way** bigger than you would normally see on your standard Internet connection. For me the comparison is between 150ms as shown above, and 15ms on a Virgin Media cable modem link. To reset the modem (for example, if you've been using it for data connectivity and you then want to use some AT commands again), the simplest way seems to be to unload and reload the kernel modules for it:rmmod qcserial rmmod qmi_wwan modprobe qcserial modprobe qmi_wwan ===== Warning ===== Once you have a network connection running, **do not** run minicom, or any further commands such as # qmicli -d /dev/cdc-wdm0 --device-open-proxy --dms-get-ids # qmicli -d /dev/cdc-wdm0 --get-expected-data-format # qmicli -d /dev/cdc-wdm0 --nas-get-signal-strength. You will get an answer to the command, but it will amost certainly break your network connection, and you'll have to rmmod and modprobe as above, then bring up the network link again manually (assuming you don't want to do a reboot). ===== Don't panic ===== Some documentation you will find (including some that's linked from this page) suggests that you can do a quick-and-dirty minicom replacement using:cat /dev/ttyUSB1 This will appear to work, however the next time you start minicom (or for all I know, the next time you try to do anything that involves ttyUSB1) you will find that the application locks up and cannot talk to the modem. If it's minicom, you can't even exit (although you can cleanly kill it from another login session). You then find that you can't rmmod the qcserial module:# rmmod qcserial rmmod: ERROR: Module qcserial is in use [[https://superuser.com/questions/572034/how-to-restart-ttyusb|Here]] is how to kill the process/es which are locking the device:# ls -alR /sys/bus/usb/drivers/qcserial /sys/bus/usb/drivers/qcserial: total 0 drwxr-xr-x 2 root root 0 Mar 3 15:05 . drwxr-xr-x 12 root root 0 Mar 3 10:29 .. lrwxrwxrwx 1 root root 0 Mar 3 15:12 1-1.3:1.0 -> ../../../../devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1.3/1-1.3:1.0 lrwxrwxrwx 1 root root 0 Mar 3 15:12 1-1.3:1.2 -> ../../../../devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1.3/1-1.3:1.2 --w------- 1 root root 4096 Mar 3 15:12 bind lrwxrwxrwx 1 root root 0 Mar 3 15:12 module -> ../../../../module/usbserial --w------- 1 root root 4096 Mar 3 15:05 uevent --w------- 1 root root 4096 Mar 3 15:12 unbind # echo "1-1.3:1.2" >/sys/bus/usb/drivers/qcserial/unbind (kill from another terminal any process which got stuck trying to use ttyUSB1) # rmmod qcserial # modprobe qcserial Minicom, or anything else which needs to use ttyUSB1, will now be happy again. Alternatively, if you know what process is connected to ttyUSB1, you can simply kill that with the same effect:# ps ax | grep cat 8815 pts/1 S 0:00 cat 8846 pts/0 S+ 0:00 grep cat # kill 8815 This is a much simpler and quicker solution if you know what you did to lock up the device, but the slightly more complex approach outlined above will work for any process whether you know what it is or not. ===== Full configuration ===== The above outlines the manual steps involved in getting the device working, but there are a few other things you can do to automate it on bootup, or just to name the interface the way you want it, etc. Here is my full configuration for using a Lebara SIM card (which means I'd like the interface to be named Lebara instead of wwan0) based in the UK (although these cards to Europe-wide roaming as well) and setting up an OpenVPN connection to a server I rent in a data centre (so, it's got a static IP address and is almost guranteed to be running at any given time). The OpenVPN link allows me to SSH in to the firewall containing the SIM card even when its primary network link (Virgin Media) is down. Note that the mobile data link is **only** used for the OpenVPN link - no other data goes across that route, to minimise data usage on the SIM card. The intention here is provide an emergency access route into the equipment, not to provide a backup route for general Internet connectivity (that could also be done, but isn't what I wanted to achieve). I also use the data connection in 802.3 (not raw-ip) mode. 1. Renaming the interface and bringing it up - includes IProute2 advanced routing and starting the OpenVPN link: rename wwan0=Lebara auto Lebara iface Lebara inet dhcp pre-up for _ in $(seq 1 10); do /usr/bin/test -c /dev/cdc-wdm0 && break; /bin/sleep 1; done pre-up for _ in $(seq 1 10); do /usr/bin/qmicli -d /dev/cdc-wdm0 --nas-get-signal-strength && break; /bin/sleep 1; done pre-up for _ in $(seq 1 10); do /usr/bin/qmi-network /dev/cdc-wdm0 start && break; /bin/sleep 1; done post-up ip route add default dev Lebara table Lebara post-up ip rule add fwmark 42 table Lebara post-up /etc/init.d/openvpn start MyVPN pre-down /etc/init.d/openvpn stop MyVPN post-down /usr/bin/qmi-network /dev/cdc-wdm0 stop 2. Additions to my firewall rules: iptables -A POSTROUTING -t nat -o Lebara -j MASQUERADE iptables -t mangle -A OUTPUT -p udp -d data.centre.IP --dport 1194 -j MARK --set-mark 42 3. Addition to the IProute2 table definitions (for routing **only** the OpenVPN traffic to my Data Centre server over the mobile data link)42 Lebara 4. Defining the OpenVPN connection (started from /etc/network/interfaces, above): client dev tun-DataCentre proto udp mssfix 1259 remote Data.Centre.Server.DNS 1194 connect-retry 2 60 resolv-retry infinite nobind persist-key persist-tun ca /etc/openvpn/ca.crt cert /etc/openvpn/MyVPN.crt key /etc/openvpn/MyVPN.key remote-cert-tls server cipher AES-256-CBC reneg-sec 21600 verb 2 script-security 2 The interface named Lebara should now appear after a reboot, and acquire a DHCP address over the mobile network, the OpenVPN tunnel will be started automatically, and you can connect between OpenVPN clients as well as client <-> server. For reference, here is the OpenVPN server's configuration file: mode server port 1194 proto udp dev tun ca /etc/openvpn/easy-rsa/pki/ca.crt cert /etc/openvpn/easy-rsa/pki/issued/DataCentre.crt key /etc/openvpn/easy-rsa/pki/private/DataCentre.key dh /etc/openvpn/easy-rsa/pki/dh.pem reneg-sec 21600 topology subnet tls-server push "topology subnet" ifconfig 10.0.42.254 255.255.255.0 ifconfig-pool 10.0.42.10 10.0.42.99 255.255.255.0 push "route-gateway 10.0.42.254" client-config-dir /etc/openvpn/client client-to-client ifconfig-pool-persist ipp.txt keepalive 5 30 cipher AES-256-CBC max-clients 256 user nobody group nogroup persist-key persist-tun status /var/log/openvpn/openvpn-status.log verb 3 explicit-exit-notify 1 ===== Problem ===== The one problem I've found after using the device for a few days is that with sustained data uploads, the mobile interface simply disappears. Downloads are fine (if slow) but saturated upstream data manages to disconnect the USB interface: kernel: [99260.265155] usb 1-1.3: USB disconnect, device number 11 kernel: [99260.265889] qcserial ttyUSB0: Qualcomm USB modem converter now disconnected from ttyUSB0 kernel: [99260.266008] qcserial 1-1.3:1.0: device disconnected kernel: [99260.266703] qcserial ttyUSB1: Qualcomm USB modem converter now disconnected from ttyUSB1 kernel: [99260.266786] qcserial 1-1.3:1.2: device disconnected kernel: [99260.274290] qmi_wwan 1-1.3:1.3 Lebara: unregister 'qmi_wwan' usb-0000:00:13.0-1.3, WWAN/QMI device charon: 09[KNL] interface Lebara deactivated The device immediately gets detected again, and I've implemented a cron job to restart the interface and the OpenVPN link, but there's definitely something very weird going on when data transfers can actually disconnect the USB interface. ===== Also ===== Nice discussion / guidance about using a Quectel EC25 (which I don't think I'll get for €5 - more like €50):\\ https://github.com/geerlingguy/raspberry-pi-pcie-devices/issues/344 https://forums.quectel.com/uploads/short-url/xnztA07u1c4hilREu66LYIY6NGR.pdf also distinctly suggests that [[https://www.quectel.com/wp-content/uploads/2021/09/Quectel_EC25_Series_Mini_PCIe_LTE_Standard_Specification_V2.2.pdf|this thing]] can do voice as well. Useful notes on AT commands: https://www.emnify.com/developer-blog/at-commands-for-cellular-modules\\ AT commands for configuring APN: https://support.emnify.com/hc/en-us/articles/4401906757906 More on AT commands: https://www.smssolutions.net/tutorials/gsm/\\ https://www.smssolutions.net/tutorials/ ---- [[.:|Go up]]\\ Return to [[:|main index]].