OpenWRT on WNR3500L + E3272 in NCM
Written by pmd - - no comments⚫ Installed OpenWRT on WNR3500L
root@192.168.1.1's password:
BusyBox v1.35.0 (2023-04-27 20:28:15 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 22.03.5, r20134-5f15225c1e
-----------------------------------------------------
root@OpenWrt:~#
[OpenWrt Wiki] NETGEAR WNR3500U/WNR3500L
I wanted to install 24.10.0 but it was impossible to connect to a wifi and install all necessary packets.
I installed 22.03.5.
⚫ Expected configuration
One OpenWRT router getting internet access through a 4G USB dongle using NCM connection (much faster than PPP).
⚫ Preparing
Update package list:
Install necessary packets to manage e3272 huawei 4g usb stick:
Install package to have wifi N available:
Install some tools for editing files and communicate with 4g usb stick:
Activate USB port power supply:
# nvram set boardflags=0x00000710
# nvram commit
Remove b43 wifi driver whci does not enable wifi N:
# rm /etc/modules.d/b43 (probably unecessary)
Here switch OFF the router, and switch ON.
Router will be using brcmsmac wifi driver so you can use wifi N (WNR3500L v1 woking perfectly but wifi in Wireless-G only).
For information there is another propriatory driver available which might have better performances but I didn't get it working (broadcom-wl). It takes too much space (I used this script to free the space when opkg couln't install fully)
Router is ready to be configured.
⚫ Configuration of e3272 stick
Disconnect from previously connected wifi.
See some information about the USB 4g stick e3272 here: OpenWRT on GL-AR750 + E3372 in NCM + receive SMS (2023) - pmd
Go to Network > Interfaces and create Add new interface... with following parameters:
| Protocol => NCM
| Bring up on boot => YES
| Modem device => /dev/cdc-wdm0
| Network Mode => LTE
| IP Protocol => IPv4
| APN => mmsbouygtel.com
Firewall setting:
| Assign firewall-zone as => wan
Save and apply and after this router should be connected to internet (check modem led not blinking anymore).
For information this is how to discuss with modem with AT commands continuously or in one line for shell script:
picocom v3.1
port is : /dev/ttyUSB1
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
!! Settings mismatch !! Type [C-a] [C-v] to see actual port settings
Type [C-a] [C-h] to see available commands
Terminal ready
AT
OK
AT+CSQ
+CSQ: 11,99
OK
ERROR
AT^SETPORT?
^SETPORT:FF;10,12,16,A1,A2
OK
<<<<<<<<<<<<<<<<<< here I did CTRL+A then CTRL+X
Terminating...
Thanks for using picocom
root@OpenWrt:~#
root@OpenWrt:~# echo -e "AT+CSQ\r" | picocom -b 115200 -q --exit-after 2000 /dev/ttyUSB1
AT+CSQ
+CSQ: 10,99
OK
root@OpenWrt:~#
⚫ Get APN in command line
mmsbouygtel.com
root@OpenWrt:~#
⚫ Find best place for USB 4g stick
Once the modem is connected, you can use this file to monitor signal strength to find the best place for USB 4g stick.
#!/bin/sh
DEVICE="/dev/ttyUSB1" # update as necessary
if [ ! -e "$DEVICE" ]; then
echo "Erreur : $DEVICE introuvable"
exit 1
fi
echo "Lecture du signal AT+CSQ via $DEVICE (Ctrl+C pour arrêter)..."
while true; do
# On lit toute la sortie de picocom
RAW_OUTPUT=$(echo -e "AT+CSQ\r" | picocom -b 115200 -q --exit-after 2000 "$DEVICE" 2>/dev/null)
# On filtre uniquement la ligne avec +CSQ
RESPONSE=$(echo "$RAW_OUTPUT" | grep "+CSQ:" | tr -d '\r')
if [ -n "$RESPONSE" ]; then
echo -n "$(date +%H:%M:%S) -> $RESPONSE"
VALUE=$(echo "$RESPONSE" | cut -d ':' -f2 | cut -d ',' -f1 | tr -d ' ')
case "$VALUE" in
[0-9]) QUAL=" (Très faible)" ;;
1[0-4]) QUAL=" (Moyen)" ;;
1[5-9]) QUAL=" (Bon)" ;;
2[0-9]|3[0-1]) QUAL=" (Excellent)" ;;
99) QUAL=" (Inconnu)" ;;
*) QUAL=" (?)" ;;
esac
echo "$QUAL"
else
echo "$(date +%H:%M:%S) -> Pas de réponse"
sleep 1
fi
#sleep 1
done
root@OpenWrt:~# chmod +x /root/csq_monitor2.sh
root@OpenWrt:~# /root/csq_monitor2.sh
Lecture du signal AT+CSQ via /dev/ttyUSB1 (Ctrl+C pour arrêter)...
19:23:22 -> +CSQ: 11,99 (Moyen)
19:23:26 -> +CSQ: 11,99 (Moyen)
19:23:29 -> +CSQ: 11,99 (Moyen)
19:23:33 -> +CSQ: 11,99 (Moyen)
19:23:36 -> +CSQ: 11,99 (Moyen)
19:23:40 -> +CSQ: 11,99 (Moyen)
19:23:43 -> +CSQ: 11,99 (Moyen)
19:23:47 -> +CSQ: 11,99 (Moyen)
19:23:51 -> +CSQ: 11,99 (Moyen)
^CTerminated
root@OpenWrt:~#
⚫ Fix modem disconnection automatically
Inspiration scripts from here: https://openwrt.org/docs/guide-user/network/wan/wwan/ethernetoverusb_ncm
Create a shell script that will ping an adress every minute to check connectivity status:
----------
#!/bin/sh
# Enter the FQDNs you want to check with ping (space separated)
# Script does nothing if any tries to any FQDN succeeds
FQDN="www.google.com"
FQDN="$FQDN www.amd.com"
FQDN="$FQDN www.juniper.net"
# Sleep between ping checks of a FQDN (seconds between pings)
SLEEP=3 # Sleep time between each retry
RETRY=3 # Retry each FQDN $RETRY times
SLEEP_MAIN=60 # Main loop sleep time
SLEEP_RESTSTART_NETWORK=240 # Waiting time before retrying after an interface reset
check_connection()
{
for NAME in $FQDN; do
for i in $(seq 1 $RETRY); do
ping -c 1 $NAME > /dev/null 2>&1
if [ $? -eq 0 ]; then
#echo "ping $NAME OK"
#echo "ping $NAME OK" | logger -t "connectivityCheck.sh[$$]" -p info
return 0
fi
#echo "ping $NAME NOK"
echo "ping $NAME NOK" | logger -t "connectivityCheck.sh[$$]" -p info
sleep $SLEEP
done
done
# If we are here, it means all failed
return 1
}
echo "Starting connectivityCheck.sh" | logger -t "connectivityCheck.sh[$$]" -p info
while true; do
check_connection
if [ $? -ne 0 ]; then
echo "All ping for connectivity check failed... Trying reconnecting..." | logger -t "connectivityCheck.sh[$$]" -p info
/etc/init.d/ncm-network start
sleep $SLEEP_RESTSTART_NETWORK
else
sleep $SLEEP_MAIN
fi
done
As you see, above script will be calling /etc/init.d/ncm-network if connectivity is lost.
Let's create it:
----------
#!/bin/sh /etc/rc.common
# Interface to send AT commands
DEVICE='/dev/ttyUSB1'
# Interface name from /etc/config/network
IFNAME='wwan4g'
# Your APN:
APN=$(uci get network.wwan4g.apn)
START=70
STOP=90
start() {
if [ -e ${DEVICE} ]; then
ifdown $IFNAME
sleep 3
echo -n "1-1" > /sys/bus/usb/drivers/usb/unbind
sleep 3 # waiting for USB disconnection
echo -n "1-1" > /sys/bus/usb/drivers/usb/bind
sleep 10 # waiting for USB connection
echo -ne "AT^NDISDUP=1,0\r\n" > ${DEVICE}
echo "AT^NDISDUP=1,0 > ${DEVICE}" | logger -t "ncm-network[$$]" -p info
sleep 3 # wait for disconnect
echo -ne "AT+CGATT=0\r\n" > ${DEVICE}
echo "AT+CGATT=0 > ${DEVICE}" | logger -t "ncm-network[$$]" -p info
sleep 3 # wait for detach from network
echo -ne "AT+CFUN=0\r\n" > ${DEVICE}
echo "AT+CFUN=0 > ${DEVICE}" | logger -t "ncm-network[$$]" -p info
sleep 10 # wait for activate plane mode
echo -ne "AT+CFUN=1\r\n" > ${DEVICE}
echo "AT+CFUN=1 > ${DEVICE}" | logger -t "ncm-network[$$]" -p info
sleep 10 # wait for deactivate plane mode (activate radio)
#echo -ne "AT^NDISDUP=1,1,\"${APN}\"\r\n" > ${DEVICE}
#echo "AT^NDISDUP=1,1,\"${APN}\" > ${DEVICE}" | logger -t "ncm-network[$$]" -p info
#sleep 3 # wait for connect
ifup $IFNAME
echo "/etc/init.d/ncm-network start ${DEVICE} executed" | logger -t "ncm-network[$$]" -p info
else
echo "No such device ${DEVICE}" | logger -t "ncm-network[$$]" -p info
fi
}
stop() {
if [ -e ${DEVICE} ]; then
ifdown $IFNAME
sleep 3
echo -ne "AT^NDISDUP=1,0\r\n" > ${DEVICE}
echo "AT^NDISDUP=1,0 > ${DEVICE}" | logger -t "ncm-network[$$]" -p info
echo "/etc/init.d/ncm-network stop ${DEVICE} executed" | logger -t "ncm-network[$$]" -p info
else
echo "No such device ${DEVICE}" | logger -t "ncm-network[$$]" -p info
fi
}
Above script will be restarting the network if connectivity loss is confirmed by /root/connectivityCheck.sh.
To have /root/connectivityCheck.sh monitoring connectivity status, you need to start it at rooter startup. In luci interface, go to System > Startup > Local startup and add this lines before exit 0:
/root/connectivityCheck.sh &
exit 0
⚫ Identify Wi-Fi connection as metered automatically
Identify Wi-Fi connection as metered on Android automatically
Extract from /etc/config/dhcp:
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
list dhcp_option '43,ANDROID_METERED'
Identify Wi-Fi connection as metered on Windows automatically (see next link to have it working on Windows AND iOS)
Identify Wi-Fi connection as metered on Windows and iOS automatically (see section Mimicking an iOS hotspot)
Extract from /etc/config/wireless (so you need to apply it on all wifi Access Point):
option type 'mac80211'
option path 'bcm47xx_soc/bcma0:1'
option band '2g'
option cell_density '0'
option htmode 'HT20'
option channel '11'
option legacy_rates '1'
option txpower '19'
list hostapd_options 'vendor_elements=DD0A0017F206010103010000'