This guide covers the complete cellular connection setup for your Raspberry Pi with SIMCOM SIM7600G-H modem. Three complementary scripts work together to provide reliable, automatic connection management.
Cellular carriers use DHCP-like assignment pools. Each time you reboot, the modem gets a different IP address from the carrier's pool. Hardcoded addresses become invalid, breaking connectivity.
- Carrier assigns addresses dynamically: Unlike fixed broadband, cellular networks assign temporary IPs from a pool
- Each connection gets new addresses: When you reconnect (reboot), you get different addresses
- Manual configuration breaks: Hardcoded IPs from a previous session no longer work
The solution uses three complementary scripts:
-
connect-cellular-robust.sh(Recommended for production)- Handles modem state management
- Disconnects existing bearers before creating new ones
- Delegates DNS/routes to helper script
- Works reliably after each reboot
-
connect-cellular-dynamic.sh(For troubleshooting)- Manually extracts and configures IP addresses
- Shows detailed configuration information
- Useful for understanding what the modem assigns
-
auto-recover.sh(For high availability)- Continuous monitoring daemon (every 30 seconds)
- Automatically detects and recovers from connection loss
- Checks routes, DNS, IP connectivity, and DNS resolution
The robust script handles initial connection:
- Connects to the modem using ModemManager
- Queries the modem for the assigned IP configuration
- Extracts the actual addresses from
mmcli -b 1output - Configures the interface with the correct addresses
- Works reliably after each reboot because it uses whatever addresses the carrier assigns
# Step 1: Enable modem and create bearer
mmcli -m 0 --enable
mmcli -m 0 --create-bearer="apn=ereseller,ip-type=ipv4v6"
# Step 2: Connect the bearer
mmcli -b 1 --connect
# Step 3: Query modem for assigned configuration
mmcli -b 1
# Output shows:
# IPv4 configuration | method: static
# | address: 10.19.145.184
# | prefix: 28
# | gateway: 10.19.145.185
# | dns: 172.26.38.2
# Step 4: Extract and use the addresses
IPV4_ADDRESS="10.19.145.184"
IPV4_PREFIX="28"
GATEWAY="10.19.145.185"
DNS="172.26.38.2"
# Step 5: Configure interface with extracted values
ip addr add 10.19.145.184/28 dev wwan0
ip route add default via 10.19.145.185 dev wwan0# If scripts are in current directory
chmod +x ./connect-cellular-robust.sh
chmod +x ./connect-cellular-dynamic.sh
chmod +x ./auto-recover.sh
chmod +x ./setup-dns-routes.sh
# Or if installed in /opt/cellular
chmod +x /opt/cellular/*.shFor production use, run the robust script:
# If in current directory
sudo ./connect-cellular-robust.sh
# Or if installed in /opt/cellular
sudo /opt/cellular/connect-cellular-robust.shFor troubleshooting and detailed inspection, run the dynamic script:
# If in current directory
sudo ./connect-cellular-dynamic.sh
# Or if installed in /opt/cellular
sudo /opt/cellular/connect-cellular-dynamic.sh[INFO] Starting cellular connection setup...
[INFO] Step 1: Enabling modem 0...
[INFO] Modem enabled successfully
[INFO] Step 2: Creating bearer with APN=ereseller, IP-Type=ipv4v6...
[INFO] Bearer created successfully
[INFO] Step 3: Connecting bearer 1...
[INFO] Bearer connected successfully
[INFO] Step 4: Bringing up interface wwan0...
[INFO] Interface brought up
[INFO] Step 5: Retrieving IP configuration from modem...
[INFO] Retrieved configuration:
[INFO] IPv4 Address: 10.19.145.184
[INFO] Prefix: 28
[INFO] Gateway: 10.19.145.185
[INFO] DNS: 172.26.38.2
[INFO] Step 6: Configuring interface with retrieved addresses...
[INFO] IP address configured: 10.19.145.184/28
[INFO] Default route added: via 10.19.145.185
[INFO] Step 7: Setting MTU to 1430...
[INFO] MTU set to 1430
[INFO] Step 8: Configuring DNS...
[INFO] DNS configured: 172.26.38.2
[INFO] Step 9: Verifying connectivity...
[INFO] Interface configured successfully
[INFO] Connectivity test PASSED - can reach 8.8.8.8
==========================================
Cellular connection established!
==========================================
Interface: wwan0
IP Address: 10.19.145.184/28
Gateway: 10.19.145.185
DNS: 172.26.38.2
MTU: 1430
==========================================
For high availability, start the auto-recovery daemon:
# If in current directory
sudo nohup ./auto-recover.sh 30 > ./auto-recover.log 2>&1 &
# Or if installed in /opt/cellular
sudo nohup /opt/cellular/auto-recover.sh 30 > /var/log/cellular/auto-recover.log 2>&1 &
# Set custom log directory via environment variable
export CELLULAR_LOG_DIR=/var/log/cellular
sudo -E nohup ./auto-recover.sh 30 &Monitor the daemon:
# Default location
tail -f ./auto-recover.log
# Or system log location
tail -f /var/log/cellular/auto-recover.logCreate /etc/systemd/system/cellular-connect.service:
[Unit]
Description=Cellular Modem Connection
After=network.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/opt/cellular/connect-cellular-robust.sh
RemainAfterExit=yes
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetNote: Update ExecStart path to match your installation directory.
Create /etc/systemd/system/cellular-auto-recover.service:
[Unit]
Description=Cellular Auto-Recovery Daemon
After=cellular-connect.service
Wants=cellular-connect.service
[Service]
Type=simple
ExecStart=/bin/bash -c 'exec /opt/cellular/auto-recover.sh 30'
Environment="CELLULAR_LOG_DIR=/var/log/cellular"
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetNote: Update ExecStart path and CELLULAR_LOG_DIR to match your setup.
Enable and start both:
sudo systemctl daemon-reload
sudo systemctl enable cellular-connect.service cellular-auto-recover.service
sudo systemctl start cellular-connect.service cellular-auto-recover.serviceCheck status:
sudo systemctl status cellular-connect.service
sudo systemctl status cellular-auto-recover.service
sudo journalctl -u cellular-connect.service -f
sudo journalctl -u cellular-auto-recover.service -fAdd to /etc/rc.local before exit 0:
/opt/cellular/connect-cellular-robust.sh >> /var/log/cellular-connect.log 2>&1 &
sleep 5
export CELLULAR_LOG_DIR=/var/log/cellular
nohup /opt/cellular/auto-recover.sh 30 >> /var/log/cellular-auto-recover.log 2>&1 &Note: Update paths to match your installation directory.
Cause: The modem hasn't finished connecting yet
Solution: Increase the sleep time after mmcli -b $BEARER_ID --connect:
sleep 5 # Increase from 2 to 5 secondsCause: Carrier may block external traffic or have firewall rules
Solution: This is normal for some carriers. Test with your actual server instead:
ping -I wwan0 your-server-ipCause: Interface needs to be brought up after configuration
Solution: The script already does this, but you can manually verify:
sudo ip link set wwan0 up
ip addr show wwan0Cause: DNS server may be unreachable or incorrect
Solution: Check /etc/resolv.conf and verify DNS:
cat /etc/resolv.conf
nslookup google.comCause: Daemon may have crashed or not started
Solution: Check daemon status and logs:
ps aux | grep auto-recover.sh
tail -f /var/log/cellular/auto-recover.logRestart the daemon:
sudo pkill -f auto-recover.sh
export CELLULAR_LOG_DIR=/var/log/cellular
sudo -E nohup /opt/cellular/auto-recover.sh 30 &Cause: Modem may need reset or bearer may be unstable
Solution: Use emergency modem reset:
sudo bash /opt/cellular/reset-modem.sh
sudo /opt/cellular/connect-cellular-robust.shNote: Update paths to match your installation directory.
Then start auto-recovery daemon to prevent future drops
mmcli -m 0mmcli -b 1ip addr show wwan0
ip route show dev wwan0mmcli -m 0 -wping -I wwan0 8.8.8.8
curl --interface wwan0 https://httpbin.org/ip| Feature | Dynamic | Robust | Auto-Recover |
|---|---|---|---|
| IP Configuration | Manual extraction | Delegated to helper | N/A |
| Modem State Management | Basic | Advanced | N/A |
| Bearer Cleanup | No | Yes | N/A |
| DNS/Routes | Manual | Delegated | Monitors |
| Continuous Monitoring | No | No | Yes |
| Connection Recovery | Manual | Manual | Automatic |
| Best For | Troubleshooting | Production | High Availability |
| Reboot Reliability | ✅ Works | ✅ Works | ✅ Works |
| Error Handling | Comprehensive | Comprehensive | Comprehensive |
| Logging | Detailed | Detailed | Continuous |
The carrier assigns addresses using CIDR notation:
- Address: 10.19.145.184 (your device's IP)
- Prefix: 28 (network mask, /28 = 255.255.255.240)
- Gateway: 10.19.145.185 (carrier's gateway for this connection)
The /28 prefix means:
- Network: 10.19.145.176/28
- Usable IPs: 10.19.145.177 - 10.19.145.190
- Broadcast: 10.19.145.191
The MTU (Maximum Transmission Unit) of 1430 is typical for cellular:
- Standard Ethernet: 1500 bytes
- Cellular (with overhead): 1430 bytes
- Setting correct MTU prevents packet fragmentation
The carrier provides DNS servers (172.26.38.2):
- These are the carrier's DNS resolvers
- May be different from public DNS (8.8.8.8)
- Script uses carrier's DNS for reliability
-
Test the robust script:
sudo /opt/cellular/connect-cellular-robust.sh
-
Verify connectivity:
ip addr show wwan0 ping -I wwan0 8.8.8.8
-
Start auto-recovery daemon:
export CELLULAR_LOG_DIR=/var/log/cellular sudo -E nohup /opt/cellular/auto-recover.sh 30 &
-
Reboot and verify it still works:
sudo reboot # After reboot, check: ip addr show wwan0 mmcli -m 0 tail -f /var/log/cellular/auto-recover.log -
Set up automatic startup using systemd services (recommended)
-
Monitor logs to ensure it's working:
sudo journalctl -u cellular-connect.service -f sudo journalctl -u cellular-auto-recover.service -f
-
Test the dynamic script for detailed inspection:
sudo /opt/cellular/connect-cellular-dynamic.sh
-
Check modem status:
mmcli -m 0 mmcli -b 1
-
Review logs:
sudo journalctl -xe
-
Use debug script for comprehensive diagnostics:
sudo /opt/cellular/cellular-debug.sh status sudo /opt/cellular/cellular-debug.sh test
If you encounter issues:
-
Check modem detection:
mmcli -L
-
Verify ModemManager is running:
sudo systemctl status ModemManager
-
Check system logs:
sudo journalctl -xe
-
Test with minicom (for AT commands):
sudo minicom -D /dev/ttyUSB2 AT+CPIN? AT+COPS?