# Fibocom FM350-GL 5G Modem Configuration Guide Complete reference for configuring the Fibocom FM350-GL modem on Alpine Linux. ## Working Configuration | Setting | Value | |---------|-------| | **Modem** | Fibocom FM350-GL | | **USB ID** | 0e8d:7126 (Mode 40) | | **AT Port** | /dev/ttyUSB1 | | **Network Interface** | eth1 (RNDIS) | | **APN** | internet (CYTA Cyprus) | ## AT Command Reference ### Sending AT Commands The FM350-GL doesn't need `stty` configuration. Send commands directly: ```bash # Pattern for sending AT commands cat /dev/ttyUSB1 & CAT_PID=$! sleep 0.3 echo -e 'YOUR_COMMAND\r' > /dev/ttyUSB1 sleep 2 kill $CAT_PID 2>/dev/null ``` ### Essential Commands | Command | Purpose | Example Response | |---------|---------|------------------| | `AT` | Test communication | `OK` | | `AT+CGMI` | Manufacturer | `Fibocom Wireless Inc.` | | `AT+CGMM` | Model | `FM350-GL` | | `AT+CSQ` | Signal strength | `+CSQ: 7, 99` (7 = moderate) | | `AT+CREG?` | Network registration | `+CREG: 0,1` (1 = registered) | | `AT+CEREG?` | LTE/5G registration | `+CEREG: 0,1` | | `AT+CCID` | SIM card ID | `+CCID: 893570...` | ### APN Configuration ```bash # Set APN (CYTA Cyprus uses "internet") echo -e 'AT+CGDCONT=1,"IP","internet"\r' > /dev/ttyUSB1 # Verify APN is set echo -e 'AT+CGDCONT?\r' > /dev/ttyUSB1 # Response: +CGDCONT: 1,"IP","internet",""... ``` ### Connection Management ```bash # Activate PDP context (start data connection) echo -e 'AT+CGACT=1,1\r' > /dev/ttyUSB1 # Response: +CGEV: ME PDN ACT 1, OK # Get assigned IP address echo -e 'AT+CGPADDR=1\r' > /dev/ttyUSB1 # Response: +CGPADDR: 1,"10.156.167.104","" # Get full connection details (DNS, MTU) echo -e 'AT+CGCONTRDP=1\r' > /dev/ttyUSB1 # Response includes DNS servers ``` ### USB Mode Control ```bash # Check current USB mode echo -e 'AT+GTUSBMODE?\r' > /dev/ttyUSB1 # Response: +GTUSBMODE: 40 # Available modes echo -e 'AT+GTUSBMODE=?\r' > /dev/ttyUSB1 # Response: +GTUSBMODE: (40,41) # Switch modes (requires modem reset) echo -e 'AT+GTUSBMODE=40\r' > /dev/ttyUSB1 # Reset modem echo -e 'AT+CFUN=1,1\r' > /dev/ttyUSB1 ``` ## USB Modes | Mode | USB Product ID | Description | AT Commands | |------|----------------|-------------|-------------| | 40 | 0e8d:7126 | RNDIS mode | ✅ Work on ttyUSB1 | | 41 | 0e8d:7127 | Extended mode | ❌ Don't work | **Important:** Stay in Mode 40 for reliable AT command access. ## Network Interface Configuration ### Why DHCP Doesn't Work The RNDIS interface (`eth1`) does **not** provide DHCP. The modem does not assign an IP to the host via DHCP. You must: 1. Get the IP from the modem via **`AT+CGPADDR=1`** 2. Optionally get DNS via **`AT+CGCONTRDP=1`** (connection dynamic parameters) 3. Configure the interface and `/etc/resolv.conf` manually The **connect-5g.sh** script does exactly this: it uses AT commands only (no DHCP on eth1), then sets `ip addr` and default route on eth1, and DNS from modem or from config. ### Manual Configuration ```bash # Get IP from modem (replace with actual value) MODEM_IP="10.156.167.104" # Configure interface ip link set eth1 up ip addr flush dev eth1 ip addr add $MODEM_IP/32 dev eth1 ip route add default dev eth1 metric 50 # Test ping -c 3 8.8.8.8 ``` ## CYTA Cyprus Settings | Setting | Value | |---------|-------| | APN | `internet` | | DNS Primary | 195.14.130.220 | | DNS Secondary | 195.14.154.100 | | Network Name | Vodafone | ## Complete Connection Sequence ```bash #!/bin/sh # Full connection sequence for FM350-GL with CYTA SIM AT_PORT="/dev/ttyUSB1" APN="internet" # 1. Configure APN cat $AT_PORT & PID=$!; sleep 0.3 echo -e "AT+CGDCONT=1,\"IP\",\"$APN\"\r" > $AT_PORT sleep 2; kill $PID 2>/dev/null # 2. Activate connection cat $AT_PORT & PID=$!; sleep 0.3 echo -e "AT+CGACT=1,1\r" > $AT_PORT sleep 3; kill $PID 2>/dev/null # 3. Get IP address MODEM_IP=$(timeout 5 sh -c " cat $AT_PORT & PID=\$! sleep 0.3 echo -e 'AT+CGPADDR=1\r' > $AT_PORT sleep 2 kill \$PID 2>/dev/null " 2>&1 | grep CGPADDR | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1) echo "Modem IP: $MODEM_IP" # 4. Configure interface ip link set eth1 up ip addr flush dev eth1 ip addr add $MODEM_IP/32 dev eth1 ip route add default dev eth1 metric 50 # 5. Test ping -c 3 8.8.8.8 ``` ## Troubleshooting ### Run full diagnostic (modem not responding after reboot) **When the modem does not respond** after a reboot, run the full troubleshoot script on the device to collect all logs and checks: ```bash # On the device (SSH or console) /usr/local/bin/troubleshoot-5g.sh ``` If the script is not installed yet, deploy first (`./scripts/deploy.sh` or `./scripts/install.sh` on the device), or run from the repo: ```bash ./scripts/troubleshoot-5g.sh ``` The script prints: - **dmesg** (last 40 lines) – kernel messages about USB/tty - **lsusb** – modem present and Mode 40 (7126) vs Mode 41 (7127) - **/dev/ttyUSB*** – whether each port is a character device or a broken regular file - **AT test** on the configured port (with 3s wait, like connect-5g.sh) - **AT probe** on each ttyUSB port – which port returns OK - **5g-router service** status - **WAN interface** and default route - **Last 60 lines** of `/var/log/5g-router.log` - **Processes using the AT port** (lsof) – see if ModemManager or another process is holding the port - **modem-status-at.sh** output (registration, signal) if installed Copy the full output and use it to see: wrong AT port, broken ttyUSB node, modem in Mode 41, another process holding the port, or service/APN issues. Then apply the fixes listed at the end of the script or in the sections below. ### AT Commands Not Responding / "AT not OK" **Symptoms:** No response to AT commands, or connect script logs "AT not OK". **Solutions:** 1. **Wait longer** – The modem can take 2–4 seconds to respond. The script now waits 3 s for the initial AT. If you still see "AT not OK", increase the wait in `get_at_response` or in config. 2. Check modem is in Mode 40: `lsusb | grep 7126` 3. If in Mode 41 (7127), AT commands won't work - need physical access to switch back 4. **Try different ports** – On FM350-GL the AT port is often ttyUSB1, but it can be ttyUSB0 or another. Test manually: ```bash ( timeout 5 cat /dev/ttyUSB1 & ); sleep 0.5; echo -e 'AT\r' > /dev/ttyUSB1; sleep 3; kill %1 2>/dev/null ``` If you see `OK` in the output, that port works. Set `AT_PORT="/dev/ttyUSB1"` (or the working port) in `/etc/5g-router.conf`. 5. **Ensure no other process is holding the port** (e.g. ModemManager, a stuck `cat`, or the Web GUI polling modem-status-at.sh). Run `lsof /dev/ttyUSB1` to see who has it open. Stop ModemManager if present: `rc-service ModemManager stop`. If the 5g-router service is stuck with an open `cat`, restart it: `service 5g-router restart`. ### ttyUSB port shows as regular file (AT not responding) **Symptoms:** `ls -la /dev/ttyUSB1` shows `-rw-rw----` (regular file) instead of `crw-rw----` (character device). AT commands get no reply or garbage. **Cause:** A **shell redirect** to `/dev/ttyUSB1` when the device **does not exist yet** (e.g. modem not bound, or device removed) **creates a regular file** at that path. That file then “steals” the name: when the kernel later creates the real modem port, it may get a different name (e.g. ttyUSB5). Typical causes: - A script or cron job (e.g. Web GUI status poll, modem-status-at.sh) runs **before** the modem is ready and does `echo ... > /dev/ttyUSB1`. - The 5g-router service runs at boot; between “port available” and sending AT, the modem briefly disappears (USB glitch) and the next write creates a file. - ModemManager or another daemon opening the port when it doesn’t exist. **Prevention:** All project scripts that write to the AT port now check `[ -c "$AT_PORT" ]` immediately before writing and skip/exit if it’s not a character device, so they never create a regular file. The connection script also removes a stray `/dev/ttyUSB` (no number) file at startup. **Fix (one-time):** ```bash # Replace N with the port number (0, 1, 2, …) rm -f /dev/ttyUSB1 mknod /dev/ttyUSB1 c 188 1 chmod 660 /dev/ttyUSB1 chown root:dialout /dev/ttyUSB1 ``` **Prevention:** `connect-5g.sh` now checks and fixes a broken AT port automatically before use (recreates the device node if it is a regular file). Scripts never write to the port unless it is currently a character device, so they don’t create the file in the first place. ### Stray /dev/ttyUSB file (no number) **Symptoms:** Troubleshoot shows `/dev/ttyUSB` as a regular file (no digit). Real ports are ttyUSB0, ttyUSB1, etc. **Fix:** Remove the stray file. The connection script now removes it automatically; you can also run: `rm -f /dev/ttyUSB` ### ttyUSB3 Shows as Regular File (legacy) **Symptoms:** `ls -la /dev/ttyUSB3` shows `-rw-r--r--` instead of `crw-rw----` **Fix:** ```bash rm -f /dev/ttyUSB3 mknod /dev/ttyUSB3 c 188 3 chmod 660 /dev/ttyUSB3 chown root:dialout /dev/ttyUSB3 ``` ### stty Errors **Symptoms:** `stty: /dev/ttyUSB1: cannot perform all requested operations` **Solution:** Don't use `stty`. Send AT commands directly with `echo` and `cat`. ### No IP on eth1 / Could not get modem IP **Symptoms:** `ip addr show eth1` shows no inet address; or connect script logs "Could not get modem IP". **Solutions:** 1. RNDIS doesn't use DHCP. The script gets the IP from `AT+CGPADDR=1`; if the operator hasn't assigned one yet, it retries a few times. Wait and re-run the connection script. 2. Check registration and signal: run `AT+CEREG?` (expect `,1` or `,5` for registered) and `AT+CSQ` (signal strength). If not registered or no signal, fix antenna/SIM/location. 3. Ensure APN is correct for your operator (e.g. `internet` for CYTA). 4. Try activating PDP again: `AT+CGACT=1,1` then wait 5–10 s and `AT+CGPADDR=1`. ### ModemManager Not Detecting Modem **Note:** ModemManager doesn't work well with this modem in RNDIS mode. Use AT commands directly instead. ### Signal Strength Interpretation | CSQ Value | dBm | Quality | |-----------|-----|---------| | 0 | -113 or less | No signal | | 1-9 | -111 to -95 | Poor | | 10-14 | -93 to -85 | Fair | | 15-19 | -83 to -75 | Good | | 20-30 | -73 to -53 | Excellent | | 31 | -51 or better | Excellent | | 99 | Unknown | - | ## Kernel Modules These modules should be loaded for MBIM/QMI support (optional): ```bash modprobe cdc-wdm modprobe cdc_mbim modprobe qmi_wwan modprobe cdc_ncm # Verify lsmod | grep -E '(cdc|qmi)' ``` ## Files on Device | Path | Purpose | |------|---------| | `/usr/local/bin/connect-5g.sh` | Auto-connection script | | `/usr/local/bin/troubleshoot-5g.sh` | Full diagnostic (logs + AT/USB checks) | | `/etc/init.d/5g-router` | OpenRC service | | `/var/log/5g-router.log` | Connection log | | `/etc/iptables/rules.v4` | Firewall/NAT rules | ## Service Management ```bash # Check status service 5g-router status # Restart connection service 5g-router restart # View logs tail -f /var/log/5g-router.log # Check if enabled at boot rc-update show | grep 5g-router ```