Portable Linux helper package for Fibocom FM350-GL / Dell DW5931e-eSIM 5G modem in USB RNDIS + AT mode.
This project provides a repeatable way to use the FM350-GL modem on Linux machines through:
- NetworkManager
- USB RNDIS network interface
- AT command control port
- automatic modem/interface detection
- terminal diagnostics similar to a lightweight NetMonster view
Main validated setup:
Q370 / Manjaro KDE
Fibocom FM350-GL / Dell DW5931e-eSIM
USB ID: 0e8d:7127
GTUSBMODE: 41
NetworkManager
RNDIS interface: enp0s20f0u3
AT port: /dev/ttyUSB3
Polish documentation is available in:
README_PL.md
fm350_portable automates setup and runtime handling for the FM350-GL modem in:
RNDIS + AT mode
The package can:
- detect the FM350-GL modem by USB ID,
- detect the AT command port,
- detect the RNDIS network interface,
- create a NetworkManager profile named
FM350_RNDIS, - activate the cellular data context over AT,
- assign the modem-provided IP address to the RNDIS interface,
- set the default route through the modem,
- enforce DNS while the modem connection is active,
- provide
fm350info, a terminal-based FM350 diagnostic tool.
Tested modem:
Fibocom FM350-GL / Dell DW5931e-eSIM
Supported USB IDs:
0e8d:7127 GTUSBMODE=41
0e8d:7126 GTUSBMODE=40
Primary tested mode:
GTUSBMODE=41
fm350_portable/
├── bootstrap.sh
├── install_fm350.fish
├── uninstall_fm350.fish
├── fm350-detect
├── fm350-connect
├── fm350-disconnect
├── fm350info
├── dispatcher/
│ ├── 90-fm350-rndis
│ └── 95-fm350-dns-guard
├── .gitignore
├── README.md
└── README_PL.md
Clone the repository:
git clone https://github.com/torpix/fm350_portable.git
cd fm350_portableRun the bootstrap script:
sh ./bootstrap.shThe bootstrap script checks dependencies and runs:
sudo fish ./install_fm350.fish --autoconnect yesReboot after installation:
sudo rebootAfter reboot:
fm350-detect
fm350info
ip route get 1.1.1.1Install base dependencies:
sudo pacman -S --needed git fish networkmanager ethtool usbutils iproute2Install atinout if it is not already available. On Arch-based systems it may be available through AUR, for example with yay or pamac.
Then run:
sudo fish ./install_fm350.fish --autoconnect yes
sudo rebootInstall dependencies:
sudo apt update
sudo apt install -y git fish network-manager ethtool usbutils iproute2 atinoutThen run:
sudo fish ./install_fm350.fish --autoconnect yes
sudo rebootinstall_fm350.fish performs the following steps:
- Detects the FM350-GL modem.
- Detects the AT command port, for example:
/dev/ttyUSB3
- Detects the RNDIS network interface, for example:
enp0s20f0u3
- Writes the runtime configuration to:
/etc/fm350-rndis.conf
Example configuration:
FM_IF="enp0s20f0u3"
AT_PORT="/dev/ttyUSB3"
APN="internet"
DNS1="1.1.1.1"
DNS2="8.8.8.8"
DNS3="9.9.9.9"
ROUTE_METRIC="100"
AUTOCONNECT="yes"
DISABLE_MODEMMANAGER_FOR_FM350="yes"
- Installs helper scripts:
/usr/local/sbin/fm350-detect
/usr/local/sbin/fm350-connect
/usr/local/sbin/fm350-disconnect
/usr/local/bin/fm350info
- Installs NetworkManager dispatcher scripts:
/etc/NetworkManager/dispatcher.d/90-fm350-rndis
/etc/NetworkManager/dispatcher.d/95-fm350-dns-guard
- Creates or updates the NetworkManager connection:
FM350_RNDIS
- Enables autoconnect if requested:
--autoconnect yesThis package does not globally mask ModemManager by default.
This is intentional. Some laptops may contain an additional internal LTE modem, for example a Dell WWAN module. Globally disabling ModemManager could break that device.
Instead, this package is designed to keep ModemManager away from the FM350-GL by matching the FM350 USB ID.
Global ModemManager masking is available only as an explicit option:
sudo fish ./install_fm350.fish --autoconnect yes --mask-modemmanagerUse this only if you intentionally want to disable ModemManager system-wide.
The AT port usually looks like this:
crw-rw---- root uucp /dev/ttyUSB3
The installer detects the port group and adds the installing user to that group, for example:
uucp
After installation, log out and log back in, or reboot:
sudo rebootWithout a new login session, fm350info may still require sudo.
fm350info prints:
- operator,
- LTE/5G registration state,
- signal data,
- Cell ID / TAC / PCI / channel data,
- LTE/NR bands,
- carrier aggregation information,
- active APN,
- modem IP address,
- Linux routing state,
- DNS state.
Run:
fm350infoFallback:
sudo fm350infoCommands used internally include:
AT+COPS?
AT+CEREG?
AT+CGREG?
AT+CSQ
AT+CESQ
AT+GTCCINFO?
AT+GTCAINFO?
AT+GTACT?
AT+CGACT?
AT+CGPADDR=1
AT+CGCONTRDP=1
Common FM350 band code mapping used by this package:
101 = LTE B1
103 = LTE B3
107 = LTE B7
120 = LTE B20
128 = LTE B28
501 = NR n1
503 = NR n3
5028 = NR n28
5078 = NR n78
Example output:
PCC:5078 ... -109
PCC:101 ... -105
SCC 1:103 ...
Interpretation:
5G NR n78
LTE B1
LTE B3 as secondary carrier
After installation:
nmcli connection show --active | grep -E 'FM350|LAN'
ip -br addr
ip route get 1.1.1.1
cat /etc/resolv.conf
curl -4 --interface <FM_IF> -I --max-time 20 https://speed.cloudflare.comExample for the Q370 test machine:
curl -4 --interface enp0s20f0u3 -I --max-time 20 https://speed.cloudflare.comExpected result:
HTTP/1.1 200 OK
Connect through NetworkManager:
sudo nmcli connection up FM350_RNDISDisconnect:
sudo nmcli connection down FM350_RNDISDirect helper scripts:
sudo fm350-connect
sudo fm350-disconnectRun:
sudo fish ./uninstall_fm350.fishThe uninstaller removes:
- FM350 helper scripts,
- FM350 dispatcher scripts,
- optional NetworkManager profile entries.
It does not remove system packages, does not remove ModemManager, and does not modify unrelated LAN profiles.
Do not use old scripts that communicate with the modem through patterns such as:
cat /dev/ttyUSBx
printf ... > /dev/ttyUSBxIf the serial port disappears, such code may accidentally create a regular file in /dev, for example:
/dev/ttyUSB3
That can break modem detection.
This project uses:
atinout + timeout + character device checks
Before using an AT port, scripts verify that it is a character device:
[ -c "$AT_PORT" ]Typical log files:
/tmp/fm350-rndis.log
/tmp/fm350-rndis-dispatcher.log
/tmp/fm350-dns-guard.log
/tmp/fm350info-UID.log
fm350info uses a per-user log file:
/tmp/fm350info-1000.log
Lack of write access to a log file should not block AT command execution.
Check USB and serial devices:
lsusb
ls -l /dev/ttyUSB*
sudo fm350-detectManual AT port test:
for p in /dev/ttyUSB*; do
if [ -c "$p" ]; then
echo "### $p"
printf 'ATE0\nATI\nAT+GTUSBMODE?\n' | sudo timeout 10s atinout - "$p" -
fi
doneCheck:
ip -br addr
ip route get 1.1.1.1
cat /etc/resolv.conf
curl -4 --interface <FM_IF> -I --max-time 20 https://speed.cloudflare.comCheck group membership:
groups
stat -c '%U %G %a %n' /dev/ttyUSB3If the user is not in the port group, rerun the installer or add the user to the group manually.
After changing groups, log out and log back in or reboot.
Check:
ip route get 1.1.1.1
nmcli connection show --activeForce the modem connection:
sudo nmcli connection up FM350_RNDISValidated on:
Q370 / Manjaro KDE
FM350-GL / Dell DW5931e-eSIM
USB ID: 0e8d:7127
GTUSBMODE: 41
NetworkManager
RNDIS interface: enp0s20f0u3
AT port: /dev/ttyUSB3
Confirmed:
reboot autostart: OK
FM350_RNDIS active: OK
default route through modem: OK
HTTP through modem: OK
fm350info without sudo: OK
per-user fm350info log: OK
Pending:
Dell Precision 7510 / Manjaro
Dell 7220 / Kali
different interface names
different AT port numbers
different SIM/operator
antenna and modem placement tests
git clone https://github.com/torpix/fm350_portable.git
cd fm350_portable
sh ./bootstrap.sh
sudo reboot
fm350info
ip route get 1.1.1.1Q370: PASS
Dell Precision 7510: pending
Dell 7220 / Kali: pending
torpix
This is a practical helper package for personal Linux infrastructure and FM350-GL modem testing.