Saturday, May 3, 2014

Advanced band selection for OpenWRT/luci/Huawei modems

I have a wonderful OpenWRT on a nice TPLink 842 router, and I want to add band selection for LTE and selective UMTS - 900 and 2100 Mhz.
I have E3276 (not in NCM mode!) and several 3G (E1552,E1762) modems. I had to add the folowing:
                       elif echo "$cardinfo" | grep -q "Sierra Wireless"; then
                       elif echo "$cardinfo" | grep -q "MF823"; then
                                case "$service" in
                                        umts_only) CODE="5";;
                                        umts900_only) CODE="5";;
                                        umts2100_only) CODE="5";;
                                        gprs_only) CODE="4";;
                                        gprs900_only) CODE="4";;
                                        gprs1800_only) CODE="4";;
                                        lte_only) CODE="7";;
                                        lte_b7_only) CODE="7";;
                                        lte_b20_only) CODE="7";;

                                export MODE="AT+ZPREFMODE=${CODE}"
                        elif echo "$cardinfo" | grep -qi "E327"; then
# E327 means both E3276 and E3272 at least; correct for your's 4G model
# 00000100 is EGSM900, 00000200 is primary GSM900
                                case "$service" in
                                        umts_only) CODE="02";;
                                        umts900_only) CODE="02"
                                        umts2100_only) CODE="02"
                                        gprs_only) CODE="01";;
                                        gprs900_only) CODE="01"
                                        gprs1800_only) CODE="01"
                                        lte_only) CODE="03";;
                                        lte_b7_only) CODE="03"
                                        lte_b20_only) CODE="03"
                                        *) CODE="00";;
                                export MODE="AT^SYSCFGEX=\"${CODE}\",${BAND},1,4,${LTEBAND},\"\",\"\""
                        elif echo "$cardinfo" | grep -qi huawei; then
                                case "$service" in
                                        lte_only) CODE="14,2";;
                                        lte_b7_only) CODE="14,2";;
                                        lte_b20_only) CODE="14,2";;
                                        umts_only) CODE="14,2";;
                                        umts900_only) CODE="14,2"
                                        umts2100_only) CODE="14,2"
                                        gprs_only) CODE="13,1";;
                                        gprs900_only) CODE="13,1"
                                        gprs1800_only) CODE="13,1"
                                        *) CODE="2,2";;
                                export MODE="AT^SYSCFG=${CODE},${BAND},2,4"

and in /usr/lib/lua/luci/model/cbi/admin_network/proto_3g.lua
service = section:taboption("general", Value, "service", translate("Service Type"))
service:value("", translate("-- Please choose --"))
service:value("umts", "UMTS/GPRS")
service:value("umts_only", translate("UMTS only"))
service:value("umts900_only", translate("UMTS 900 only"))
service:value("umts2100_only", translate("UMTS 2100 only"))
service:value("gprs_only", translate("GPRS only"))
service:value("gprs900_only", translate("GPRS 900 only"))
service:value("gprs1800_only", translate("GPRS 1800 only"))
service:value("lte_only", translate("LTE only"))
service:value("lte_b7_only", translate("LTE Band 7 only"))
service:value("lte_b20_only", translate("LTE Band 20 only"))
service:value("evdo", "CDMA/EV-DO")

To see how gcom sets the mode, add in /etc/gcom/setmode.gcom:
 print "Trying to set mode ",$env("MODE")," (at /etc/gcom)\n"

And you can monitor by logread -f and see something like that:

Sat May  3 16:06:53 2014 daemon.notice netifd: Interface '3g' is setting up now
Sat May  3 16:06:55 2014 daemon.notice netifd: 3g (10250): Trying to set mode AT^SYSCFGEX="03",3FFFFFFF,1,4,7FFFFFFFFFFFFFFF,"","" (at /etc/gcom)
Sat May  3 16:06:57 2014 daemon.notice pppd[10273]: pppd 2.4.5 started by root, uid 0
Sat May  3 16:06:58 2014 chat[10275]: abort on (BUSY)

UPD 20140627:
  • Also works with E3272 [Megafon-100?] (change grep -qi "E3276"; to grep -qi "E327"; to support both modems)
  • Has a bug in 4G/LTE band selection. Instead of 1st ($CODE) , the 5th (7FFFFFFFFFFFFFFF) parameter should be changed. If I ever test this on real hardware, I'll update the post.
UPD 20150502: Fixed 4G band selection. UPD 20150801: Some code for ZTE 823D added, it must be in AT-command mode and it cannot select bands, just switches from GSM to UMTS and LTE. That's the only ZTE modem I own for now, so I cannot say if any other model will do the same stuff, check it.


  1. Hi DtZ, this is a good article. I,m an Indonesian. I would like to ask you. Your script is can be add in the old script or the old script must be change? My English bad :D

    1. This should be treat as a patch for the existing script. I always do that by vi editor inside a working OpenWRT box.
      Open the files I mention and add this strings.

      However, if you are new to this (and vi editor), be sure to make a backups of this files first ;-)

    2. Can you help me to edit my script? but, I think is too long if I type the script here.

  2. Log in into openwrt via ssh.

    To backup /usr/lib/lua/luci/model/cbi/admin_network/proto_3g.lua file, type

    # cp /usr/lib/lua/luci/model/cbi/admin_network/proto_3g.lua /usr/lib/lua/luci/model/cbi/admin_network/proto_3g.lua.bak
    To edit /usr/lib/lua/luci/model/cbi/admin_network/proto_3g.lua, type

    # vi /usr/lib/lua/luci/model/cbi/admin_network/proto_3g.lua

    And, well, you have to learn vi editor. And I'm not ready to teach you ;-)