commit 1136a332b542b16ca9c5b6ff25c5fe916d5d32fc Author: nearxos Date: Mon Feb 2 00:26:20 2026 +0200 Initial commit: Alpine 5G Router with Fibocom FM350-GL modem configuration - Complete working configuration for FM350-GL modem - CYTA Cyprus APN setup (internet) - AT command reference and troubleshooting guide - Configuration scripts and documentation - RNDIS mode working with manual IP configuration diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63f8b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Logs +*.log +/var/log/ + +# Temporary files +*.tmp +*.swp +*~ + +# OS files +.DS_Store +Thumbs.db + +# Backup files +*.bak +*.backup diff --git a/5G_MODEM_TROUBLESHOOTING.md b/5G_MODEM_TROUBLESHOOTING.md new file mode 100644 index 0000000..5ba7117 --- /dev/null +++ b/5G_MODEM_TROUBLESHOOTING.md @@ -0,0 +1,258 @@ +# 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 manages the connection internally. You must: + +1. Get the IP from the modem via `AT+CGPADDR=1` +2. Configure the interface manually + +### 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 + +### AT Commands Not Responding + +**Symptoms:** No response to AT commands on any port. + +**Solutions:** +1. Check modem is in Mode 40: `lsusb | grep 7126` +2. If in Mode 41 (7127), AT commands won't work - need physical access to switch back +3. Try different ports: ttyUSB0, ttyUSB1, ttyUSB2 + +### ttyUSB3 Shows as Regular File + +**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 + +**Symptoms:** `ip addr show eth1` shows no inet address after DHCP attempt. + +**Solution:** RNDIS doesn't use DHCP. Configure IP manually from `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 | +| `/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 +``` diff --git a/Fibocom_FM350_AT Commands User Manual_V2.10.pdf b/Fibocom_FM350_AT Commands User Manual_V2.10.pdf new file mode 100644 index 0000000..066974a Binary files /dev/null and b/Fibocom_FM350_AT Commands User Manual_V2.10.pdf differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a7a6aa5 --- /dev/null +++ b/README.md @@ -0,0 +1,212 @@ +# Alpine 5G Router - Raspberry Pi 5 + Fibocom FM350-GL + +A complete 5G router setup using Alpine Linux on Raspberry Pi 5 with a Fibocom FM350-GL modem. + +## ✅ Status: Working + +The 5G modem is fully operational with CYTA Cyprus SIM card. + +## Documentation + +| File | Description | +|------|-------------| +| [README.md](README.md) | This file - overview and quick start | +| [5G_MODEM_TROUBLESHOOTING.md](5G_MODEM_TROUBLESHOOTING.md) | Complete modem configuration reference | +| [configure_fm350_5g.sh](configure_fm350_5g.sh) | Configuration script for the modem | + +## Hardware + +- **Board:** Raspberry Pi 5 +- **Modem:** Fibocom FM350-GL (USB ID: 0e8d:7126) +- **OS:** Alpine Linux v3.23.3 +- **SIM:** CYTA Cyprus (APN: `internet`) + +## Network Architecture + +``` +Internet (CYTA 5G) + │ + ▼ + FM350-GL Modem + (RNDIS eth1) + │ + ▼ + Raspberry Pi 5 + Alpine Linux + │ + ▼ + eth0.100 VLAN + (192.168.1.1) + │ + ▼ + LAN Clients +``` + +## Quick Start + +### 1. Install Required Packages + +```bash +# Enable community repository +sed -i 's|#.*community|http://mirrors.neterra.net/alpine/v3.23/community|' /etc/apk/repositories +apk update + +# Install packages +apk add modemmanager dnsmasq iptables libmbim-tools qmi-utils +``` + +### 2. Configure and Connect Modem + +```bash +# Set APN for CYTA +cat /dev/ttyUSB1 & CAT_PID=$! +sleep 0.3 +echo -e 'AT+CGDCONT=1,"IP","internet"\r' > /dev/ttyUSB1 +sleep 2 +kill $CAT_PID + +# Activate connection +cat /dev/ttyUSB1 & CAT_PID=$! +sleep 0.3 +echo -e 'AT+CGACT=1,1\r' > /dev/ttyUSB1 +sleep 3 +kill $CAT_PID + +# Get modem IP +cat /dev/ttyUSB1 & CAT_PID=$! +sleep 0.3 +echo -e 'AT+CGPADDR=1\r' > /dev/ttyUSB1 +sleep 2 +kill $CAT_PID +# Note the IP address returned (e.g., 10.156.167.104) +``` + +### 3. Configure Network Interface + +```bash +# Replace MODEM_IP with the IP from AT+CGPADDR=1 +MODEM_IP="10.156.167.104" + +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 connectivity +ping -c 3 8.8.8.8 +``` + +### 4. Setup NAT for LAN + +```bash +# Enable IP forwarding +echo 1 > /proc/sys/net/ipv4/ip_forward + +# Configure NAT +iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE +iptables -A FORWARD -i eth0.100 -o eth1 -j ACCEPT +iptables -A FORWARD -i eth1 -o eth0.100 -m state --state RELATED,ESTABLISHED -j ACCEPT + +# Save rules +iptables-save > /etc/iptables/rules.v4 +``` + +## Key Configuration Details + +### Modem USB Modes + +| Mode | USB ID | Description | Status | +|------|--------|-------------|--------| +| 40 | 0e8d:7126 | RNDIS mode | ✅ Working | +| 41 | 0e8d:7127 | Extended mode | ❌ AT broken | + +**Important:** Stay in Mode 40 - AT commands work on `/dev/ttyUSB1`. + +### Working AT Commands + +| Command | Description | +|---------|-------------| +| `AT` | Test communication | +| `AT+CSQ` | Signal strength | +| `AT+CGDCONT=1,"IP","internet"` | Set APN | +| `AT+CGACT=1,1` | Activate connection | +| `AT+CGPADDR=1` | Get assigned IP | +| `AT+CGCONTRDP=1` | Get DNS servers | +| `AT+GTUSBMODE?` | Check USB mode | + +### CYTA Cyprus Network Info + +- **APN:** `internet` +- **DNS Primary:** 195.14.130.220 +- **DNS Secondary:** 195.14.154.100 + +## Services + +The following services are configured to start on boot: + +```bash +# Check service status +rc-status + +# Services enabled: +# - dnsmasq (DHCP/DNS) +# - iptables-restore (firewall rules) +# - 5g-router (connection script) +``` + +## Files on Device + +| Path | Purpose | +|------|---------| +| `/usr/local/bin/connect-5g.sh` | Startup connection script | +| `/etc/init.d/5g-router` | OpenRC service | +| `/etc/init.d/iptables-restore` | Firewall restore service | +| `/etc/iptables/rules.v4` | Saved firewall rules | +| `/etc/dnsmasq.conf` | DHCP configuration | +| `/etc/network/interfaces` | Network configuration | +| `/var/log/5g-router.log` | Connection log | + +## Troubleshooting + +### Modem not responding to AT commands + +1. Check modem is in Mode 40: `lsusb | grep 7126` +2. Use `/dev/ttyUSB1` for AT commands +3. Don't use `stty` - send commands directly + +### DHCP not working on eth1 + +This is normal - RNDIS mode doesn't provide DHCP. Configure IP manually using the address from `AT+CGPADDR=1`. + +### Connection drops + +Re-run the connection script: +```bash +/usr/local/bin/connect-5g.sh +``` + +Or restart the service: +```bash +service 5g-router restart +``` + +## Verification Commands + +```bash +# Check modem +lsusb | grep -i fibocom + +# Check network +ip addr show eth1 +ip route show + +# Test connectivity +ping -c 3 8.8.8.8 +ping -c 3 google.com + +# Check NAT rules +iptables -t nat -L -n -v + +# View logs +tail -f /var/log/5g-router.log +``` diff --git a/configure_fm350_5g.sh b/configure_fm350_5g.sh new file mode 100755 index 0000000..5ecbb73 --- /dev/null +++ b/configure_fm350_5g.sh @@ -0,0 +1,242 @@ +#!/bin/bash +# Fibocom FM350-GL 5G Modem Configuration Script +# For Alpine Linux with CYTA Cyprus SIM card +# +# This script configures the 5G modem and establishes a connection +# Usage: ./configure_fm350_5g.sh + +set -e + +# Configuration +AT_PORT="/dev/ttyUSB1" +APN="internet" +WAN_IF="eth1" +LAN_IF="eth0.100" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +send_at_cmd() { + local cmd="$1" + local wait="${2:-2}" + + cat $AT_PORT 2>/dev/null & + local CAT_PID=$! + sleep 0.3 + echo -e "${cmd}\r" > $AT_PORT + sleep $wait + kill $CAT_PID 2>/dev/null || true +} + +get_at_response() { + local cmd="$1" + local wait="${2:-2}" + + timeout $((wait + 3)) sh -c " + cat $AT_PORT 2>/dev/null & + CAT_PID=\$! + sleep 0.3 + echo -e '${cmd}\r' > $AT_PORT + sleep $wait + kill \$CAT_PID 2>/dev/null + " 2>&1 +} + +check_modem() { + log_info "Checking for FM350-GL modem..." + + if ! lsusb | grep -qi "fibocom"; then + log_error "Fibocom modem not detected via USB" + exit 1 + fi + + local usb_id=$(lsusb | grep -i fibocom | grep -oE '0e8d:[0-9a-f]+') + log_info "Modem detected: $usb_id" + + if [ "$usb_id" = "0e8d:7127" ]; then + log_warn "Modem is in Mode 41 (7127). AT commands may not work." + log_warn "Attempting to switch to Mode 40..." + fi + + if [ ! -c "$AT_PORT" ]; then + log_error "AT port $AT_PORT not available" + exit 1 + fi + + log_info "AT port available: $AT_PORT" +} + +test_at_commands() { + log_info "Testing AT command communication..." + + local response=$(get_at_response "AT" 1) + + if echo "$response" | grep -q "OK"; then + log_info "AT communication working" + return 0 + else + log_error "AT commands not responding" + return 1 + fi +} + +check_signal() { + log_info "Checking signal strength..." + + local response=$(get_at_response "AT+CSQ" 1) + local csq=$(echo "$response" | grep "+CSQ:" | grep -oE '[0-9]+' | head -1) + + if [ -n "$csq" ]; then + if [ "$csq" -lt 10 ]; then + log_warn "Signal strength: $csq (weak)" + elif [ "$csq" -lt 20 ]; then + log_info "Signal strength: $csq (moderate)" + else + log_info "Signal strength: $csq (good)" + fi + else + log_warn "Could not read signal strength" + fi +} + +configure_apn() { + log_info "Configuring APN: $APN" + + local response=$(get_at_response "AT+CGDCONT=1,\"IP\",\"$APN\"" 2) + + if echo "$response" | grep -q "OK"; then + log_info "APN configured successfully" + else + log_warn "APN configuration may have failed" + fi +} + +activate_pdp() { + log_info "Activating PDP context..." + + local response=$(get_at_response "AT+CGACT=1,1" 3) + + if echo "$response" | grep -qE "(OK|CGEV)"; then + log_info "PDP context activated" + else + log_warn "PDP activation response: $response" + fi +} + +get_modem_ip() { + log_info "Getting modem IP address..." + + local response=$(get_at_response "AT+CGPADDR=1" 2) + local ip=$(echo "$response" | grep "+CGPADDR:" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1) + + if [ -n "$ip" ]; then + log_info "Modem IP: $ip" + echo "$ip" + else + log_error "Could not get modem IP" + return 1 + fi +} + +configure_interface() { + local ip="$1" + + log_info "Configuring network interface $WAN_IF..." + + ip link set $WAN_IF up 2>/dev/null || true + ip addr flush dev $WAN_IF 2>/dev/null || true + ip addr add $ip/32 dev $WAN_IF + ip route add default dev $WAN_IF metric 50 2>/dev/null || true + + log_info "Interface configured with IP: $ip" +} + +setup_nat() { + log_info "Setting up NAT for LAN ($LAN_IF)..." + + # Enable IP forwarding + echo 1 > /proc/sys/net/ipv4/ip_forward + + # Add NAT rules (check if they exist first) + iptables -t nat -C POSTROUTING -o $WAN_IF -j MASQUERADE 2>/dev/null || \ + iptables -t nat -A POSTROUTING -o $WAN_IF -j MASQUERADE + + iptables -C FORWARD -i $LAN_IF -o $WAN_IF -j ACCEPT 2>/dev/null || \ + iptables -A FORWARD -i $LAN_IF -o $WAN_IF -j ACCEPT + + iptables -C FORWARD -i $WAN_IF -o $LAN_IF -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || \ + iptables -A FORWARD -i $WAN_IF -o $LAN_IF -m state --state RELATED,ESTABLISHED -j ACCEPT + + log_info "NAT configured" +} + +test_connectivity() { + log_info "Testing internet connectivity..." + + if ping -c 3 8.8.8.8 >/dev/null 2>&1; then + log_info "Ping to 8.8.8.8: SUCCESS" + else + log_error "Ping to 8.8.8.8: FAILED" + return 1 + fi + + if ping -c 2 google.com >/dev/null 2>&1; then + log_info "DNS resolution: SUCCESS" + else + log_warn "DNS resolution failed - check /etc/resolv.conf" + fi +} + +show_status() { + echo "" + echo "=========================================" + echo " 5G Modem Configuration Summary " + echo "=========================================" + echo "" + echo "Modem: $(lsusb | grep -i fibocom | cut -d' ' -f6-)" + echo "AT Port: $AT_PORT" + echo "APN: $APN" + echo "" + echo "Interface: $WAN_IF" + ip addr show $WAN_IF 2>/dev/null | grep -E "(state|inet )" | sed 's/^/ /' + echo "" + echo "Routing:" + ip route show | grep -E "(default|$WAN_IF)" | sed 's/^/ /' + echo "" + echo "=========================================" +} + +# Main execution +main() { + log_info "Starting FM350-GL 5G modem configuration..." + echo "" + + check_modem + test_at_commands || exit 1 + check_signal + configure_apn + activate_pdp + + local modem_ip=$(get_modem_ip) + if [ -z "$modem_ip" ]; then + log_error "Failed to get modem IP. Exiting." + exit 1 + fi + + configure_interface "$modem_ip" + setup_nat + test_connectivity + + show_status + + log_info "5G modem configuration complete!" +} + +main "$@"