Witam,
z tymi z Was którzy chcieliby podejrzeć stan procesów OpenVPN przez przeglądarkę WWW chcę się podzielić małym skryptem który w prosty sposób to umożliwi.

Do działania wymagane są:
- OpenVPN z konfiguracją przez UCI (tzn. plik /etc/config/openvpn)
- działający serwer WWW np. uhttpd
- poniższy skrypt
- kilka minut na uruchomienie

Skrypt należy wkleić do pliku /www/cgi-bin/ovpn_stat

#!/bin/sh
# OpenVPN Statistic CGI script
# Script version 1.00 Rafal Drzymala 2013
#
# Changelog
#    1.00    RD    First stable code
#

. /lib/functions.sh

print_css() {
    printf '\t<STYLE TYPE="text/css">
    @CHARSET "UTF-8";
    Body
        {
            margin: 0;
            padding: 2px;
            background-color:#000000;
            font-family: Tahoma;
            font-size: 0.8em;
            font-weight: normal;        
            color: #000000;
            scrollbar-base-color: #5C7A00; 
            scrollbar-arrow-color: #7AA300;
            scrollbar-DarkShadow-Color: #C2E066; 
        }    
    .InstanceCell
        {
            margin: 0;
            padding-top: 10px;
            padding-bottom: 10px;
            padding-left: 4px;
            padding-right: 4px;
            background-color:#296614;
            border-color: #D6EB99;
            border-style: solid;
            border-width: 2px;    
            border-radius: 8px 8px;    
            font-weight: bold;        
            text-align: center;
        }
    .InstanceText
        {
            font-size: 1.4em;
            color: #52CC29;
        }
    .SectionCell
        {
            padding: 2px;
            background-color:#47B224;
            border-color: #6B8F00;
            border-style: solid;
            border-width: 2px;    
            border-radius: 5px 5px;    
            font-weight: normal;        
            text-align: center;
        }
    .SectionText
        {
            font-size: 0.9em;
            font-weight: bold;        
            color: #2E3D00;
        }
    .ParamTable
        {
            width: 100%%;
            margin: 0;
            padding: 3px;
            background-color: #296614;
            border-style: dotted;
            border-color: #A3FF85;
            border-width: thin;    
            border-radius: 8px 8px;    
            text-align: left;
        }
    .ParamTableRow
        {
            font-size: 1em;        
            font-weight: normal;
            vertical-align: top;
        }
    .ParamTableCellName
        {
            width: 20%%;
            padding-top: 4px;
            padding-bottom: 4px;
            padding-left: 10px;
            padding-right: 10px;
            background-color:#14330A;
            border-radius: 3px 3px;    
            text-align: right;
        }
    .ParamTableTextName
        {
            font-size: 0.9em;
            font-weight: normal;        
            color: #D1FFC2;
        }
    .ParamTableCellValue
        {
            width: 80%%;
            padding-top: 4px;
            padding-bottom: 4px;
            padding-left: 10px;
            padding-right: 10px;
            background-color: #D6EB99;
            border-radius: 3px 3px;    
            text-align: left;
        }
    .ParamTableTextValue
        {
            font-size: 1em;
            font-weight: bold;        
            color: #1F4C0F;
        }
    .StatTable
        {
            width: 100%%;
            margin: 0;
            padding-top: 3px;
            padding-bottom: 3px;
            padding-left: 3px;
            padding-right: 3px;
            text-align: left;
            background-color: #99CC00;
            border-style: dotted;
            border-color: #1F4C0F;
            border-width: thin;    
            border-radius: 8px 8px;    
        }
    .StatTableHeadRow
        {
            vertical-align: top;
            background-color: #4C6600;
        }
    .StatTableHeadText
        {
            border-style: solid;
            border-color: #B8DB4D;
            border-width: 2px;
            border-radius: 5px 5px;    
            font-size: 0.7em;        
            font-style: normal;
            font-weight: normal;
            text-align: center;
            color: #D6EB99;
        }
    .StatTableOddRow
        {
            background-color: #D6EB99;
            font-size: 1em;        
            font-weight: normal;
            vertical-align: top;
        }
    .StatTableEvenRow
        {
            background-color: #E0F0B2;
            font-size: 1em;        
            font-weight: normal;
            vertical-align: top;
        }
    .StatTableCellText
        {
            padding-left: 6px;
            padding-right: 6px;
            border-radius: 3px 3px;    
            text-align: left;
            text-overflow: ellipsis;
            overflow: hidden;
            vertical-align: middle;
            color: #4C6600;
        }
    .StatTableCellNumber
        {
            padding-left: 6px;
            padding-right: 6px;
            text-align: right;
            white-space: nowrap;
            vertical-align: middle;
            color: #4C6600;
            border-radius: 3px 3px;    
        }
    .StatTableCellIP
        {
            padding-left: 6px;
            padding-right: 6px;
            border-radius: 3px 3px;    
            font-family: monospace, Consolas, Lucida Console, Terminal;
            text-align: right;
            white-space: nowrap;
            text-align: left;
            vertical-align: middle;
            color: #4C6600;
        }
    .StatTableCellMAC
        {
            padding-left: 6px;
            padding-right: 6px;
            border-radius: 3px 3px;    
            font-family: monospace, Consolas, Lucida Console, Terminal;
            text-align: right;
            white-space: nowrap;
            text-align: center;
            vertical-align: middle;
            color: #4C6600;
        }
    .StatTableCellDate
        {
            padding-left: 6px;
            padding-right: 6px;
            border-radius: 3px 3px;    
            text-align: center;
            white-space: nowrap;
            vertical-align: middle;
            color: #4C6600;
        }
    .LogArea
        {
            width: 100%%; 
            padding: 6px;
            margin-bottom: 10px;
            border-style: dotted;
            border-color: #A3FF85;
            border-width: 1px;    
            border-radius: 8px 8px;    
            background-color:#143D14;
            font-family: monospace, Consolas, Lucida Console, Terminal;
            font-size: smaller;
            text-overflow: ellipsis;
            color: #B8DB4D;
        }
    </STYLE>\n'
}

print_prefix() {
    printf "Content-type: text/html\n\n"
    printf "<!DOCTYPE html>\n"
    printf "<HTML>\n"
    printf "\t<META HTTP-EQUIV=\"pragma\" CONTENT=\"no-cache\"/>\n"
    printf "\t<META HTTP-EQUIV=\"cache-control\" CONTENT=\"no-cache\"/>\n"
    printf "\t<META HTTP-EQUIV=\"refresh\" CONTENT=\"60\">\n"
    printf "\t<META GENERATOR=\"RD_OpenVPN_Statistic\">\n"
    printf "\t<META AUTHOR=\"Rafal Drzymala\">\n"
    print_css
    printf "\t<HEAD>\n"
    printf "\t\t<TITLE>OpenVPN Statistic - $(uci get system.@system[0].hostname)</TITLE>\n"
    printf "\t</HEAD>\n"
    printf "\t<BODY>\n"
    printf "\t\t<TABLE BORDER=\"0\" WIDTH=\"100%%\">\n"
}

print_sufix() {
    printf "\t\t</TABLE>\n"
    printf "\t</BODY>\n"
    printf "</HTML>\n"
}

parse_openvpn_file() {
    local enable
    local enabled
    local status_file
    local log_file
    local status_version
    local client
    local instance
    
    config_get_bool enable  "$1" 'enable'  0
    config_get_bool enabled "$1" 'enabled' 0
    config_get status_file "$1" 'status' ""
    config_get log_file "$1" 'log' ""
    [ "$log_file" == "" ] && config_get log_file $1 'log_append'
    [ $enable -gt 0 ] && [ $enabled -gt 0 ] && return
    [ "$status_file" == "" ] && return
    [ "$log_file" == "" ] && return
    config_get_bool client "$1" 'client' 0
    config_get status_version "$1" 'status_version' "1"
    [ $client -gt 0 ] && instance="CLIENT: $1" || instance="SERVER: $1"
    printf "\t\t\t<TR>\n"
    printf "\t\t\t\t<TH CLASS=\"InstanceCell\">\n"
    printf "\t\t\t\t\t<A NAME=\"$1\">\n"
    printf "\t\t\t\t\t<DIV CLASS=\"InstanceText\">$instance</DIV>\n"
    printf "\t\t\t\t\t</A>\n"
    printf "\t\t\t\t</TH>\n"
    printf "\t\t\t</TR>\n"
    awk -v StatusVersion=$status_version '
    function AddSection(Title)
    {
        print "\t\t\t<TR>";
        print "\t\t\t\t<TH CLASS=\"SectionCell\"><DIV CLASS=\"SectionText\">",Title,"</DIV></TH>";
        print "\t\t\t</TR>";
    }
    BEGIN {
        if (StatusVersion == 3)
            FS="\t"
        else
            FS=",";
        OFS="";
        LastColCount=0;
        SubRowNo=0;
    }
    { 
        if (NF == 1 || StatusVersion == 1)
            StartCol=1
        else if ($1 == "HEADER")
            StartCol=3;
        else
            StartCol=2;
        ColCount=(NF-StartCol)+1;
        if (SubRowNo != 0 && LastColCount != ColCount) 
        {
            print "\t\t\t\t\t</TABLE>";
            print "\t\t\t\t</TD>";
            print "\t\t\t</TR>";
            SubRowNo=0;
        }
        if (StatusVersion != 1 && $1 == "HEADER") AddSection($2);
        if (ColCount == 1) 
        {
            if ($1 != "END") AddSection($1);
        } 
        else if (ColCount == 2) 
        {
            if (SubRowNo == 0) 
            {
                print "\t\t\t<TR>";
                print "\t\t\t\t<TD>";
                print "\t\t\t\t\t<TABLE CLASS=\"ParamTable\">";
            }
            print "\t\t\t\t\t\t<TR CLASS=\"ParamTableRow\">";
            print "\t\t\t\t\t\t\t<TD CLASS=\"ParamTableCellName\"><DIV CLASS=\"ParamTableTextName\">",$1,"</DIV></TD>"
            print "\t\t\t\t\t\t\t<TD CLASS=\"ParamTableCellValue\"><DIV CLASS=\"ParamTableTextValue\">",$2,"</DIV></TD>"
            print "\t\t\t\t\t\t</TR>";
            SubRowNo=SubRowNo+1;
        } 
        else 
        {
            if (SubRowNo == 0) 
            {
                print "\t\t\t<TR>";
                print "\t\t\t\t<TD>";
                print "\t\t\t\t\t<TABLE CLASS=\"StatTable\">";
            }
            if (SubRowNo == 0)
                RowCalss="StatTableHeadRow"
            else if ((SubRowNo % 2) == 0)
                RowCalss="StatTableEvenRow"
            else
                RowCalss="StatTableOddRow";
            print "\t\t\t\t\t\t<TR CLASS=\"",RowCalss,"\">";
            for (i=StartCol; i <= NF; i++) 
            {
                if (SubRowNo == 0)
                    CellClass="StatTableHeadText"
                else if ($i ~ /^[0-9]+$/)
                    CellClass="StatTableCellNumber"
                else if ($i ~ /\`([0-9a-fA-F]{1,2}[:-]){5}[0-9a-fA-F]{1,2}/)
                    CellClass="StatTableCellMAC"
                else if ($i ~ /\`([0-9]{1,3}\.){3}[0-9]{1,3}\:[0-9]{1,5}/)
                    CellClass="StatTableCellIP"
                else if ($i ~ /\`[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]{4}/)
                    CellClass="StatTableCellDate"
                else
                    CellClass="StatTableCellText";
                print "\t\t\t\t\t\t\t<TD CLASS=\"",CellClass,"\"><DIV>",$i,"</DIV></TD>"
            }
            print "\t\t\t\t\t\t</TR>";
            SubRowNo=SubRowNo+1;
        } 
        LastColCount=ColCount;
    }' $status_file
    printf "\t\t\t<TR>\n"
    printf "\t\t\t\t<TH CLASS=\"SectionCell\"><DIV CLASS=\"SectionText\">LAST LOG</DIV></TH>\n"
    printf "\t\t\t</TR>\n"
    printf "\t\t\t<TR>\n"
    printf "\t\t\t\t<TD>\n"
    printf "\t\t\t\t\t<TEXTAREA CLASS=\"LogArea\" ROWS=\"10\" READONLY=\"1\">\n"
    tail -n 50 $log_file | sed '1!G;h;$!d' 
    printf "\t\t\t\t\t</TEXTAREA>\n"
    printf "\t\t\t\t</TD>\n"
    printf "\t\t\t</TR>\n"
}

config_load openvpn
print_prefix
config_foreach parse_openvpn_file openvpn
print_sufix
# Done

jeżeli katalog nie istnieje należy go utworzyć, wydają polecenie:

mkdir /www/cgi-bin

Następnie należy nadać odpowiednie uprawnienia do skryptu, wydając polecenie:

chmod 755 /www/cgi-bin/ovpn_stat

Jeżeli serwer uhttpd nie jest jeszcze zainstalowany należy wydać polecenie:

opkg update
opkg install uhttpd
/etc/init.d/uhttpd enable
/etc/init.d/uhttpd start

Teraz wystarczy wpisać w przeglądarce adres routera i scieżkę np.:

http://192.168.1.1/cgi-bin/ovpn_stat

202

(148 odpowiedzi, napisanych Oprogramowanie / Software)

Witam,
aby serwery DHCP na routerach nie przydzielały adresów dla hostów które widzą przez VPN (czyli podpięte do innego routera) należy:

zainstalować pakiet ebtables wydając polecenie:

opkg update
opkg install kmod-ebtables-ipv4 ebtables

oraz do pliku /etc/firewall.user dodać następujące polecenia:

ebtables -F
ebtables -I FORWARD -i tap0 -p IPv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -I FORWARD -o tap0 -p IPv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -I INPUT -i tap0 -p IPv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -I OUTPUT -o tap0 -p IPv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP

Operacje tą należy wykonać na każdym routerze.

203

(148 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj,
osobiście mam konfigurację z trzema routerami, połączonymi przez VPN w LAN z jednej puli adresowej, o konfiguracji zgodnej z tym co opisałem powyżej. Nie zauważyłem takich objawów. Hosty dostają adresy z puli routera „przy którym” są.

204

(148 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj,
usuń linie option dns '192.168.1.*' z sekcji config interface 'lan' w pliku /etc/config/network.

Witaj,
idąc tropami kolegów możesz w crontab dopisać poniższą linijkę.

*/1 * * * * [ $(awk '{if ($1=="eth0.2:") print $2+$10}' /proc/net/dev) -ge 1000000000 ] && /bin/moj_skrypt.sh

Co minutę będziesz miał uruchamiany skrypt (/bin/moj_skrypt.sh) gdy transfer (bajty odebrane i wysłane) przekroczy 1000000000 bajtów na interfejsie eth0.2.
Oczywiście jeżeli ten interfejs Ciebie interesuje:)

206

(148 odpowiedzi, napisanych Oprogramowanie / Software)

Witam,
paramter no-dhcp-interface ma sens tylko w pliku /etc/dnsmasq.conf. Plik /var/etc/dnsmasq.conf jest generowany (nadpisywany) na podstawie ustawień z pliku /etc/config/dhcp, więc jego modyfikacje nie dadzą rezultatu.

Tylko z sekcji dhcp w pliku /etc/config/dhcp, które mają ustawioną opcję ignore są wstawiane parametry no-dhcp-interface do pliku  /var/etc/dnsmasq.conf (dlatego widzisz tam interfejs wan-u).

Po dodaniu no-dhcp-interface we wszystkich plikach /etc/dnsmasq.conf, powinieneś restartować routery i komputery, dopiero wtedy żaden z nich nie będzie "pamiętał" żadnych adresów.

207

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj,
jeżeli to możliwe sprawdź działanie routera z modemem w miejscu gdzie sygnał jest lepszy. Potwierdzisz w ten sposób lub nie poprawność jego konfiguracji.

208

(148 odpowiedzi, napisanych Oprogramowanie / Software)

Witam,
proponuję dodać poniższą linię do pliku /etc/dnsmasq.conf:

no-dhcp-interface=tap0

oczywiście na wszystkich routerach.

209

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Czy na notebook'u też masz do 16% siłę sygnału?

210

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Prawie się Tobie udało, niestety modem jest w trybie Circuit-Switched only, a w takim przypadku transmisji pakietowej nie będzie.

211

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Przyznam że przy takim poziomie sygnału na takich modemach E173 mnie się nie udało uzyskać połączenia.
Jeżeli do tego jeszcze masz modem wpięty bezpośrednio do routera, to układy radiowe sobie przeszkadzają i wytłumiają się nawzajem.

212

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Zmień proszę MODE na AT^SYSCFG=2,2,3FFFFFFF,2,1

213

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Coś poziom sygnału jest słaby 12%-16%!
Czy SIM-a masz bez PIN-u? (nie było pytania:)

214

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj, coś się Tobie nie udało podczas wklejania zawartości pliku ndisup.gcom.

Ale jesteś blisko:)

215

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj,
czy zmieniłeś APN, MODE i COMM tak jak pisałem w poście nr.9?

Jeżeli tak to wykonaj polecenie:

/bin/3gtester.sh

a następnie

logread -f

.

216

(34 odpowiedzi, napisanych Oprogramowanie / Software)

To teraz polecenia z punktów 5 i 6

217

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Modem po włączeniu routera gdy dostanie zasilanie powinien zacząć mrugać, tym bardziej gdy ma aktywną kartę SIM i jest w zasięgu sieci.
Podłącz do USB pendrive i zobacz czy mruga. Jeżeli podłączasz modem poprzez przedłużacz USB to spróbuj bezpośrednio podłączyć. No i na końcu podłącz modem do PC i zobacz czy działa.

218

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Będzie działać zarówno na 3420 jak i na 3220

219

(34 odpowiedzi, napisanych Oprogramowanie / Software)

A. Zmień MODE na 'AT^SYSCFG=2,2,3FFFFFFF,2,4'
B. Zmień APN na 'internet'
C. COMM powinno być '/dev/ttyUSB2'
D. Coś jest nie halo z modemem lub połączeniem USB w wynikach z punktów 5 i 6 nie widać modemu tak jak by nie był podłączony. Wydaj polecenie

echo 0 > /sys/devices/virtual/gpio/gpio6/value

następnie odczekaj kilka sekund i wydaj polecenie

echo 1 > /sys/devices/virtual/gpio/gpio6/value

napisz czy modem zareagował.

220

(34 odpowiedzi, napisanych Oprogramowanie / Software)

5. pokaż wynik cat /proc/bus/usb/devices
6. pokaż wynik ls /dev/ttyU*
7. czy przepisałeś ustawienia jw. czy dostosowałeś do swoich potrzeb?
8. czy jak włączasz router to modem nie mruga?

221

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj,
1. czy pakiety się zainstalowały bez błędów?
2. czy pliki 3gtester.sh i ndisup.gcom są na swoim miejscu?
3. czy modem nie mruga?
4. jaki operator GSM?
5. pokaż wynik cat /proc/bus/usb/devices
6. pokaż wynik ls /dev/ttyU*
7. czy przepisałeś ustawienia jw. czy dostosowałeś do swoich potrzeb?

222

(34 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj, jest możliwe, miałem dokładnie taką konfigurację. Oczywiście tylko konsola bez GUI, bo nic się nie zmieści.

Jeżeli możesz na chwilę podłączyć router do netu przez WAN to instalacja będzie wyglądać tak:
Instalujesz czysty obraz od Cezarego http://ecco.selfip.net/attitude_adjustment/ar71xx/, np. tak:

cd /tmp
wget http://ecco.selfip.net/attitude_adjustment/ar71xx/openwrt-ar71xx-generic-tl-mr3220-v1-squashfs-factory.bin
sysupgrade openwrt-ar71xx-generic-tl-mr3220-v1-squashfs-factory.bin

a potem po restarcie, instalujesz pakiety np. tak:

opkg update
opkg install libusb kmod-usb-net kmod-usb-serial kmod-usb-serial-option
opkg install kmod-usb-serial-wwan kmod-usb-net-cdc-ether usb-modeswitch-data usb-modeswitch 
opkg install chat comgt n2n

Potem wgraj pliku /bin/3gtester.sh i /etc/gcom/ndisup.gcom, znajdziesz w tym wątku http://eko.one.pl/forum/viewtopic.php?id=3276.
Następnie edycja network (np. vi /etc/config/network)

config interface 'wan2'
        option ifname 'wwan0'
        option proto 'dhcp'
        option comm '/dev/ttyUSB2'
        option apn 'darmowy'
        option mode 'AT^SYSCFG=14,2,2000000000000,1,1'
        option macaddr '00:01:02:03:04:05'
        option auto '0'
        option defaultroute '0'
        option peerdns '0'
        list dns '8.8.8.8'
        list dns '8.8.4.4'
        option rebootafter '900'

edycja firewall (np. vi /etc/config/firewall)

config 'zone'
        option 'name' 'wan'
        list 'network' 'wan'
        list 'network' 'wan2'
        option 'input' 'REJECT'
        option 'output' 'ACCEPT'
        option 'forward' 'REJECT'
        option 'masq' '1'
        option 'mtu_fix' '1'

i edycja crontab (np. crontab -e)

*/1 * * * * /bin/3gtester.sh

nie zapomnij zrobić

chmod 700 /bin/3gtester.sh

i powinno śmigać.
Oczywiście to tylko przykładowe ustawienia, a konfigurację n2n zakładam że sam zrobisz.

223

(6 odpowiedzi, napisanych Oprogramowanie / Software)

Witaj, może używasz protokołu UDP w OpenVPN. Typowe polityki zapór dopuszczają ruch na portach 80, 433 ale tylko protokół TCP.

Co do anten mam dwa przypadki gdzie stosuję anteny z modemami E173u2:

  • Połączenie z Play, antena Dipol ATK 20/850-960 MHz, osiągam bez problemów maksimum dostępne 4Mb przy sygnale 50%, BTS odległy ok. 6-7 km zasłonięty lasem. Mimo wszelkich trudności łącze jest stabilne.

  • Połączenie z Play antena Dipol ATK-LOG GSM/DCS/UMTS/HSDPA, tu także maksimum 4Mb, sygnał na poziomie <50%, BTS odległy ok. 0,5 km, kontakt wzrokowy. Centrum miasta duże zakłócenia, ale łącze bardzo stabilne.

To ostatnie wersjie skryptów:

Skrypt /bin/3gtester.sh

#!/bin/sh
# Establishing 3G modem connection in dialup or NDIS mode
# Script version 1.09 Rafal Drzymala 2012,2013
#
# Changelog
#    1.00    RD    First stable code
#    1.01    RD    Prevent from parallel comgt/gcom execution
#    1.02    RD    Added logger priority, redirect comgt/gcom to logger
#    1.03    RD    Changed ICMP monitoring, use device, multiwan or default dns
#    1.04    RD    Changed ICMP data size to 1 byte
#    1.05    RD    Changed log messages, added wwan interface detection (frutis suggestion)
#    1.06    RD    Added router auto-reboot after connection timeout detected (if rebootafter option in network present)
#    1.07    RD    Added reboots log
#    1.08    RD    Improve reboot rutine
#    1.09    RD    Small improvements
#
SCR=$(basename $0)
DEF_ICMP="8.8.8.8 8.8.4.4"
COMGT_APP="gcom"
NDISUP="/etc/gcom/ndisup.gcom"
FPATH="/usr/data/"
if ! which "$COMGT_APP" >/dev/null; then
    logger -p user.error -t $SCR "Application $COMGT_APP does not exist"
    exit
fi
[ -e "$NDISUP" ] ||    logger -p user.notice -t $SCR "Script $NDISUP does not exist"
[ -e "$FPATH" ] || mkdir -p $FPATH 
WANS=$(uci show network | awk -F[.=] '{if (($3=="proto" && $4=="3g") || ($3=="ifname" && (match($4,"usb[0-9]") || match($4,"wwan[0-9]")))) print $2}')
for WAN in $WANS; do
    NDIS="N"
    UPTIME=$(cut -d "." -f1 /proc/uptime)
    NOW=$(date -u +"%Y.%m.%d-%H:%M:%S %s")
    [ $(uci -q get network.$WAN.proto) != "3g" ] && NDIS="Y"
    DEV_IFNAME=$(uci -q get network.$WAN.ifname)
    DEV_APN=$(uci -q get network.$WAN.apn)
    DEV_PINCODE=$(uci -q get network.$WAN.pincode)
    DEV_MODE=$(uci -q get network.$WAN.mode)
    DEV_REBOOTAFTER=$(uci -q get network.$WAN.rebootafter)
    [ "$NDIS" == "Y" ] && DEV_COMM=$(uci -q get network.$WAN.comm)
    [ "$NDIS" == "N" ] && DEV_COMM=$(uci -q get network.$WAN.device)
    DEV_AUTO="1"
    [ "$NDIS" == "N" ] && DEV_AUTO=$(uci -q get network.$WAN.auto)
    DEV_ICMP=$(uci -q get network.$WAN.dns)
    [ "$DEV_ICMP" == "" ] && DEV_ICMP=$(uci -q get multiwan.$WAN.dns)
    [ "$DEV_ICMP" == "" ] && DEV_ICMP=$DEF_ICMP
    logger -p user.notice -t $SCR "Checking for active connection $WAN ($DEV_IFNAME) attempting to ping $DEV_ICMP"
    if [ "$DEV_AUTO" == "1" ]; then
        if [ -e $DEV_COMM ]; then
            echo "$NOW $UPTIME" >$FPATH$SCR.$WAN.check
            for ICMP in $DEV_ICMP; do
                if ping -q -c 1 -W 2 -s 1 -I $DEV_IFNAME $ICMP &>/dev/null; then
                    ICMP_OK=$ICMP
                    break
                fi
            done
            if [ "$ICMP_OK" != "" ]; then
                logger -p user.notice -t $SCR "ICMP successfully sent via $WAN ($DEV_IFNAME) to $ICMP_OK"
                echo "$NOW $UPTIME" >$FPATH$SCR.$WAN.ok
            else
                logger -p user.notice -t $SCR "Restarting connection $WAN ($DEV_IFNAME) using device $DEV_COMM and apn $DEV_APN"
                [ "$DEV_MODE" != "" ] && logger -p user.notice -t $SCR "Using additional modem command $DEV_MODE"
                if [ "$NDIS" == "N" ]; then
                    (ifdown $WAN; sleep 2; ifup $WAN) &
                else
                    COMGT_DEV="-d $DEV_COMM"
                    COMGT_SCR="-s $NDISUP"
                    if pgrep -l -f "$COMGT_APP $COMGT_DEV $COMGT_SCR"> /dev/null; then
                        logger -p user.notice -t $SCR "Connection $WAN ($DEV_IFNAME) is already restarted"
                    elif pgrep -l -f "$COMGT_APP $COMGT_DEV"> /dev/null; then
                        logger -p user.notice -t $SCR "Device $DEV_COMM used by another instance of $COMGT_APP"
                    elif ([ "$DEV_COMM" == "/dev/ttyUSB2" ] || [ "$DEV_COMM" == "/dev/noz2" ] || [ "$DEV_COMM" == "/dev/modem" ]) && pgrep -l -f  "$COMGT_APP" | grep -q -v "\-d"> /dev/null; then
                        logger -p user.notice -t $SCR "Device $DEV_COMM used by another instance of $COMGT_APP"
                    else
                        (ifdown $WAN; PINCODE=$DEV_PINCODE APN=$DEV_APN MODE=$DEV_MODE $COMGT_APP $COMGT_DEV $COMGT_SCR | logger -p user.notice -t $COMGT_APP; sleep 2; ifup $WAN) &
                    fi
                fi
            fi
            if [ "$DEV_REBOOTAFTER" != "" ] && [ "$UPTIME" -ge "$DEV_REBOOTAFTER" ]; then
                LAST_ICMP_CHK=$(cut -d " " -f2 $FPATH$SCR.$WAN.check)
                LAST_ICMP_OK=$(cut -d " " -f2 $FPATH$SCR.$WAN.ok)
                if [ "$LAST_ICMP_CHK" != "" ] && [ "$LAST_ICMP_OK" != "" ] && [ "$LAST_ICMP_CHK" -ge "$LAST_ICMP_OK" ]; then
                    SINCE_ICMP_OK=$(($LAST_ICMP_CHK-$LAST_ICMP_OK))
                    [ "$SINCE_ICMP_OK" -gt "0" ] && logger -p user.notice -t $SCR "Lapsing $SINCE_ICMP_OK second(s) since the last sent the correct ICMP"
                    if [ "$UPTIME" -ge "$DEV_REBOOTAFTER" ] && [ "$SINCE_ICMP_OK" -ge "$DEV_REBOOTAFTER" ]; then
                        logger -p user.notice -t $SCR "Device $WAN ($DEV_IFNAME) reboot timeout detected, rebooting router..."
                        echo "$NOW $UPTIME $WAN" >>$FPATH$SCR.reboots
                        reboot
                    fi
                fi
            fi
        else
            logger -p user.error -t $SCR "Device $DEV_COMM for $WAN not exist"
        fi
    fi
done
# Done

Skrypt /etc/gcom/ndisup.gcom

opengt
    let $x="ndisup:"+$basename($dev())+" "
    print $x+"Establishing 3G modem connection in NDIS mode\n"
    print $x+"Script for comgt version 1.07 Rafal Drzymala 2012\n"
#
# Changelog
#    1.00    RD    First stable code
#    1.01    RD    Moved "Getting received signal strength" section
#            Reset command changed from ATZ to ATZ0
#            Changed wait time for establish connection from 20 to 30 secs
#    1.02    RD    Changed signal level bar
#    1.03    RD    Added support for SYSINFOEX modem command
#    1.04    RD    Moved "Checking for password input request" section (frutis suggestion)
#    1.05    RD    Reset command changed AT+CFUN=1 to AT+CFUN=1,1
#            Corrected decode result of AT^SYSINFOEX modem command (frutis suggestion)
#    1.06    RD    Improvements dialog with modem
#            Changed waiting for establish connection rutine
#            Changed waiting for restart modem
#    1.07    RD    Improvements restart modem
#            
#
# Modem succesfuly tested
# - HUAWEI E173        11.126.85.00.209
# Modem tested, not supported 
# - HUAWEI E160G    11.608.02.02.55
# - HUAWEI E160        11.604.09.00.00
# - HUAWEI E220
#
    set com 115200n81
    set ignorecase on
    set comecho off
    set senddelay 0.02

    let $a=$env("APN")
    if $a = "" let $a=$env("COMGTAPN")
    if $a = "" print $x+"APN or COMGTAPN environment var not specified\n" goto finish    
    let $m=$env("MODE")
    let $p=$env("PINCODE")
    if $p = "" let $p=$env("COMGTPIN")
    let r1=1

:start
# Initializing communication with modem
    if r1 = 1 print $x+"Try to communicate with modem\n"
    if r1 > 1 print $x+"Again try to communicate with modem (",r1,")\n"
    waitquiet 1 0.5
    send "ATQ0; E0^m"
    waitfor 1 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while setting modem (1)\n"
    if % = 2 gosub cme_error print $x+"Error "+$e+" while setting modem (1)\n"
    if % = 3 print $x+"Command not supported (1)\n"
    send "AT+CMEE=2^m"
    waitfor 1 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while setting modem (2)\n"
    if % = 2 gosub cme_error print $x+"Error "+$e+" while setting modem (2)\n"
    if % = 3 print $x+"Command not supported (2)\n"
    send "AT\^CURC=0^m"
    waitfor 1 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while setting modem (3)\n"
    if % = 2 gosub cme_error print $x+"Error "+$e+" while setting modem (3)\n"
    if % = 3 print $x+"Command not supported (3)\n"

# Checking for password input request
    print $x+"Checking for password input request\n"
    let u=0
    send "AT+CPIN?^m"
    waitfor 5 "+CPIN: ","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while checking for password input request\n" goto end_chkpin
    if % = 2 gosub cme_error print $x+"Error "+$e+" while checking for password input request\n" goto end_chkpin
    if % = 3 print $x+"Command not supported\n" goto end_chkpin
    get 1 "^m" $i1
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    let $d="Unknown modem response ("+$i1+")"
    if $i1 = "READY" let $d="MT without password input request"
    if $i1 = "SIM PIN" let $d="UICC/SIM PIN password request"
    if $i1 = "SIM PUK" let $d="UICC/SIM PUK password request, to unblock the SIM PIN which was blocked for 3 verification failure"
    if $i1 = "SIM PIN2" let $d="PIN2 password request"
    if $i1 = "SIM PUK2" let $d="PUK2 password request, to unblock the SIM PIN2 which was blocked for 3 verification failure"
    if $i1 = "PH-SIM PIN" let $d="SIM lock (phone-to-SIM) is required"
    if $i1 = "PH-NET PIN" let $d="Network personnalisation is required"
    print $x+"- state: "+$d+"\n"
    if $i1 = "SIM PIN" goto do_pin_unlock
    if $i1 <> "READY" goto finish
:end_chkpin

# Unlock the PIN 
    goto end_pin_unlock
:do_pin_unlock
    print $x+"UICC/SIM unlocking by PIN\n"
    if $p = "" print $x+"PINCODE or COMGTPIN environment variable not specified\n" goto abort
    send "AT+CPIN="+$p"^m"
    waitfor 5 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while unlocking by PIN\n" goto abort
    if % = 2 gosub cme_error print $x+"Error "+$e+" while unlocking by PIN\n" goto abort
    if % = 3 print $x+"Command not supported\n" goto abort
    print $x+"UICC/SIM unlocked successfully\n"
    let r2=0
:wait_for_reg
    let r2=r2+1
    if r2>5 print $x+"Number of retries exhausted\n" goto abort
    print $x+"Waiting for network registration (",r2,")\n"
    send "AT+CGREG=0; +CGREG?^m"
    waitfor 2 "+CGREG: ","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while getting network registration status\n" goto end_pin_unlock
    if % = 2 gosub cme_error print $x+"Error "+$e+" while getting network registration status\n" goto end_pin_unlock
    if % = 3 print $x+"Command not supported\n" goto end_pin_unlock
    get 1 "," $i1
    if % != 0 goto comm_timeout
    get 1 "^m" $i2
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    let $i2=$left($i2,1)
    let $d="Unknown modem response ("+$i2+")"
    if $i2 = "0" goto wait_for_reg
    if $i2 = "1" goto end_pin_unlock
    if $i2 = "2" goto wait_for_reg
    if $i2 = "3" let $d="Registration rejected"
    if $i2 = "4" let $d="Unknown reasons"
    if $i2 = "5" goto end_pin_unlock
    print $x+"- error: "+$d+"\n"
    goto abort
:end_pin_unlock

# Getting device information
    print $x+"Getting device information\n"

    send "AT+CGMI^m"
    waitfor 1 "^m^j"
    if % = -1 goto comm_timeout
    get 1 "^m" $i1
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout

    send "AT+CGMM^m"
    waitfor 1 "^m^j"
    if % = -1 goto comm_timeout
    get 1 "^m" $i2
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout

    send "AT+CGMR^m"
    waitfor 1 "^m^j"
    if % = -1 goto comm_timeout
    get 1 "^m" $i3
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout

    send "AT+CGSN^m"
    waitfor 1 "^m^j"
    if % = -1 goto comm_timeout
    get 1 "^m" $i4
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout

    print $x+"- modem: "+$toupper($i1)+" "+$toupper($i2)+"\n"
    print $x+"- firmware: "+$i3+"\n"
    print $x+"- IMEI: "+$i4+"\n"
# 
#    system "export IMEI_"+$basename($dev())+"=\""+$i4+"\""


# Getting received signal strength
    print $x+"Getting received signal strength\n"
    send "AT+CSQ^m"
    waitfor 5 "+CSQ: ","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while getting received signal strength\n" goto end_sigstr
    if % = 2 gosub cme_error print $x+"Error "+$e+" while getting received signal strength\n" goto end_sigstr
    if % = 3 print $x+"Command not supported\n" goto end_sigstr
    get 1 "," $i1
    if % != 0 goto comm_timeout
    get 1 "^m" $i2
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    if $i1 = "99" print $x+"- signal strength: unknown\n" goto end_sigstr
    let s1=val($i1)
    let s2=(s1*2)-113 
    let s3=((s1*100000)/31000)
    print $x+"- signal strength: (",s1,"), ",s2," dBm, ",s3,"%\n"
    let s3=s3/2
    let $s3=$left("##################################################",s3)
    let $s3=$s3+$right("----1----2----3----5----5----6----7----8----9----$",50-s3)
    print $x+"- level: ["+$s3+"]\n"
:end_sigstr

# Checking modem for NDIS support
    print $x+"Checking modem for NDIS support\n"
    send "AT\^DIALMODE?^m" 
    waitfor 5 "\^DIALMODE:","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 2 gosub cme_error 
    if % > 0 print $x+"- This modem doesn't support NDIS mode\n" goto abort
    get 1 "^m" $i1
    if % != 0 goto comm_timeout
    let $i1=$left($i1,1)
    if $i1 = "1" goto ok_ndis_check
    if $i1 = "2" goto ok_ndis_check
    print $x+"- This modem doesn't support NDIS mode\n"
    goto abort
:ok_ndis_check
    print $x+"- NDIS mode is supported by this modem\n"

# Getting system information
    print $x+"Getting system information\n"
:do_sysinfoex
    send "AT\^SYSINFOEX^m"
    waitfor 5 "\^SYSINFOEX:","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 goto end_sysinfoex
    if % = 2 gosub cme_error goto end_sysinfoex
    if % = 3 goto end_sysinfoex
    get 1 "," $i1
    if % != 0 goto comm_timeout
    get 1 "," $i2
    if % != 0 goto comm_timeout
    get 1 "," $i3
    if % != 0 goto comm_timeout
    get 1 "," $i4
    if % != 0 goto comm_timeout
    get 1 "," $i5
    if % != 0 goto comm_timeout
    get 1 "," $i6
    if % != 0 goto comm_timeout
    get 1 "," $i7
    if % != 0 goto comm_timeout
    get 1 "," $i8
    if % != 0 goto comm_timeout
    get 1 "^m" $i9
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    let $d="Unknown modem response ("+$i1+")"
    if $i1 = "0" let $d="No service"
    if $i1 = "1" let $d="Restricted service"
    if $i1 = "2" let $d="Valid service"
    if $i1 = "3" let $d="Restricted regional service"
    if $i1 = "4" let $d="Power-saving and deep sleep state"
    print $x+"- service state: "+$d+"\n"
    let $d="Unknown modem response ("+$i2+")"
    if $i2 = "0" let $d="No service"
    if $i2 = "1" let $d="Only CS service"
    if $i2 = "2" let $d="Only PS service"
    if $i2 = "3" let $d="PS+CS service"
    if $i2 = "4" let $d="CS and PS not registered, searching"
    print $x+"- domain: "+$d+"\n"    
    let $d="Unknown modem response ("+$i3+")"
    if $i3 = "0" let $d="Non roaming state"
    if $i3 = "1" let $d="Roaming state"
    print $x+"- roaming: "+$d+"\n"
    let $d="Unknown modem response ("+$i4+")"
    if $i4 = "0" let $d="Invalid USIM card state or pin code locked"
    if $i4 = "1" let $d="Valid USIM card state"
    if $i4 = "2" let $d="USIM is invalid in case of CS"
    if $i4 = "3" let $d="USIM is invalid in case of PS"
    if $i4 = "4" let $d="USIM is invalid in case of either CS or PS"
    if $i4 = "240" let $d="ROMSIM"
    if $i4 = "255" let $d="USIM card is not existent"
    print $x+"- SIM: "+$d+"\n"
    let $d="Unknown modem response ("+$i6+")"
    if $i7 != "" let d$=$i7 let $i6=""
    if $i6 = "0" let $d="No service"
    if $i6 = "1" let $d="GSM"
    if $i6 = "2" let $d="CDMA"
    if $i6 = "3" let $d="WCDMA"
    if $i6 = "4" let $d="TD-SCDMA"
    if $i6 = "5" let $d="WIMAX"
    if $i6 = "6" let $d="LTE"
    print $x+"- mode: "+$d+"\n"
    let $d="Unknown modem response ("+$i8+")"
    if $i9 != "" let d$=$i9 let $i8=""
    if $i8 = "0" let $d="No service"
    if $i8 = "1" let $d="GSM"
    if $i8 = "2" let $d="GPRS"
    if $i8 = "3" let $d="EDGE"
    if $i8 = "21" let $d="IS95A"
    if $i8 = "22" let $d="IS95B"
    if $i8 = "23" let $d="CDMA2000 1X"
    if $i8 = "24" let $d="EVDO Rel0"
    if $i8 = "25" let $d="EVDO RelA"
    if $i8 = "26" let $d="EVDO RelB"
    if $i8 = "27" let $d="HYBRID (CDMA2000 1X)"
    if $i8 = "28" let $d="HYBRID (EVDO Rel0)"
    if $i8 = "29" let $d="HYBRID (EVDO RelA)"
    if $i8 = "30" let $d="HYBRID (EVDO RelB)"
    if $i8 = "41" let $d="WCDMA"
    if $i8 = "42" let $d="HSDPA"
    if $i8 = "43" let $d="HSUPA"
    if $i8 = "44" let $d="HSPA"
    if $i8 = "45" let $d="HSPA+"
    if $i8 = "46" let $d="DC-HSPA+"
    if $i8 = "61" let $d="TD-SCDMA"
    if $i8 = "62" let $d="HSDPA"
    if $i8 = "63" let $d="HSUPA"
    if $i8 = "64" let $d="HSPA"
    if $i8 = "65" let $d="HSPA+"
    if $i8 = "81" let $d="802.16e"
    if $i8 = "101" let $d="LTE"
    print $x+"- sub mode: "+$d+"\n"
    # Invalid state do finish
    if $i2 = "1" goto abort
    if $i4 = "0" goto abort
    if $i4 = "3" goto finish
    if $i4 = "4" goto finish
    if $i4 = "255" goto finish
    # Invalid state do restart_modem
    if $i1 = "0" goto restart_modem
    if $i1 = "4" goto restart_modem
    if $i2 = "0" goto restart_modem
    if $i2 = "4" goto restart_modem
    if $i6 = "0" goto restart_modem
    goto end_sysinfo
:end_sysinfoex

:do_sysinfo
    send "AT\^SYSINFO^m"
    waitfor 5 "\^SYSINFO:","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while getting system information\n" goto end_sysinfo
    if % = 2 gosub cme_error print $x+"Error "+$e+" while getting system information\n" goto end_sysinfo
    if % = 3 print $x+"Command not supported\n" goto end_sysinfo
    get 1 "," $i1
    if % != 0 goto comm_timeout
    get 1 "," $i2
    if % != 0 goto comm_timeout
    get 1 "," $i3
    if % != 0 goto comm_timeout
    get 1 "," $i4
    if % != 0 goto comm_timeout
    get 1 "^m" $i5
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    if len($i5)>3 let $i6=$right($i5,1)
    let $i5=$left($i5,1)
    let $d="Unknown modem response ("+$i1+")"
    if $i1 = "0" let $d="No service"
    if $i1 = "1" let $d="Restricted service"
    if $i1 = "2" let $d="Valid service"
    if $i1 = "3" let $d="Restricted regional service"
    if $i1 = "4" let $d="Power-saving and deep sleep state"
    print $x+"- service state: "+$d+"\n"
    let $d="Unknown modem response ("+$i2+")"
    if $i2 = "0" let $d="No service"
    if $i2 = "1" let $d="Only CS service"
    if $i2 = "2" let $d="Only PS service"
    if $i2 = "3" let $d="PS+CS service"
    if $i2 = "4" let $d="CS and PS not registered, searching"
    print $x+"- domain: "+$d+"\n"    
    let $d="Unknown modem response ("+$i3+")"
    if $i3 = "0" let $d="Non roaming state"
    if $i3 = "1" let $d="Roaming state"
    print $x+"- roaming: "+$d+"\n"
    let $d="Unknown modem response ("+$i4+")"
    if $i4 = "0" let $d="No service"
    if $i4 = "1" let $d="AMPS"
    if $i4 = "2" let $d="CDMA"
    if $i4 = "3" let $d="GSM/GPRS"
    if $i4 = "4" let $d="HDR"
    if $i4 = "5" let $d="WCDMA"
    if $i4 = "6" let $d="GPS"
    if $i4 = "7" let $d="GSM/WCDMA"
    if $i4 = "8" let $d="CDMA/HDR HYBRID"
    if $i4 = "15" let $d="TD-SCDMA"
    print $x+"- mode: "+$d+"\n"
    let $d="Unknown modem response ("+$i5+")"
    if $i5 = "0" let $d="Invalid USIM card state or pin code locked"
    if $i5 = "1" let $d="Valid USIM card state"
    if $i5 = "2" let $d="USIM is invalid in case of CS"
    if $i5 = "3" let $d="USIM is invalid in case of PS"
    if $i5 = "4" let $d="USIM is invalid in case of either CS or PS"
    if $i5 = "255" let $d="USIM card is not existent"
    print $x+"- SIM: "+$d+"\n"
    let $d="Unknown modem response ("+$i6+")"
    if $i6 = "0" let $d="No service"
    if $i6 = "1" let $d="GSM"
    if $i6 = "2" let $d="GPRS"
    if $i6 = "3" let $d="EDGE"
    if $i6 = "4" let $d="WCDMA"
    if $i6 = "5" let $d="HSDPA"
    if $i6 = "6" let $d="HSUPA"
    if $i6 = "7" let $d="HSDPA and HSUPA"
    if $i6 = "8" let $d="TD_SCDMA"
    if $i6 = "9" let $d="HSPA+"
    if $i6 = "17" let $d="HSPA+(64QAM)"
    if $i6 = "18" let $d="HSPA+(MIMO)"
    print $x+"- sub mode: "+$d+"\n"
    # Invalid state do finish
    if $i2 = "1" goto abort
    if $i5 = "0" goto abort
    if $i5 = "3" goto finish
    if $i5 = "4" goto finish
    if $i5 = "255" goto finish
    # Invalid state do restart_modem
    if $i1 = "0" goto restart_modem
    if $i1 = "4" goto restart_modem
    if $i2 = "0" goto restart_modem
    if $i2 = "4" goto restart_modem
    if $i4 = "0" goto restart_modem
:end_sysinfo

# Getting network registration status
    print $x+"Getting network registration status\n"
    let $i2=""
    send "AT+CGREG=2; +CGREG?^m"
    waitfor 2 "+CGREG: ","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while getting network registration status\n" goto end_cgreg
    if % = 2 gosub cme_error print $x+"Error "+$e+" while getting network registration status\n" goto end_cgreg
    if % = 3 print $x+"Command not supported\n" goto end_cgreg
    get 1 "," $i1
    if % != 0 goto comm_timeout
    get 1 "^m" $i4
    if % != 0 goto comm_timeout
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    let $i2=$left($i4,1)
    if len($i4)>2 let $i3=$mid($i4,2,len($i4)-2)
    let $d="Unknown modem response ("+$i2+")"
    if $i2 = "0" let $d="Not registered. The MS is not searching the new operators to be registered"
    if $i2 = "1" let $d="Local network is registered"
    if $i2 = "2" let $d="Not registered. But the MS is searching the new operators to be registered"
    if $i2 = "3" let $d="Registration rejected"
    if $i2 = "4" let $d="Unknown reasons"
    if $i2 = "5" let $d="Roaming network is registered"
    print $x+"- status: "+$d+"\n"
    print $x+"- lac, ci: "+$i3+"\n"
    send "AT+CGREG=0^m"
    waitfor 1 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 2 gosub cme_error
:end_cgreg

# Disable CME error report
    send "AT+CMEE=0^m"
    waitfor 1 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while setting modem (4)\n"
    if % = 2 gosub cme_error print $x+"Error "+$e+" while setting modem (4)\n"
    if % = 3 print $x+"Command not supported (4)\n"
    
# Verify if the modem is connected to APN
    print $x+"Verify if the modem is connected to APN\n"
    send "AT\^DHCP?^m"
    waitfor 5 "\^DHCP:","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 0 print $x+"Modem is already connected\n" goto do_disconnect
    if % = 2 gosub cme_error
    if % = 3 print $x+"Command not supported\n" goto abort
    print $x+"No connection detected\n"
    goto end_disconnect
:do_disconnect
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout

# Disconnecting from current APN
    print $x+"Disconnecting from current APN\n"
    send "AT\^NDISDUP=1,0^m"
    waitfor 5 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while disconnecting from current APN\n" goto abort
    if % = 2 gosub cme_error print $x+"Error "+$e+" while disconnecting from current APN\n" goto abort
    if % = 3 print $x+"Command not supported\n" goto abort
    print $x+"Disconnected successfully\n"
:end_disconnect    

# Setting mode
    if $m = "" goto end_mode_set
    print $x+"Setting mode "+$m+"\n"
    send $m+"^m"
    waitfor 5 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while setting mode error\n" goto abort
    if % = 2 gosub cme_error print $x+"Error "+$e+" while setting mode error\n" goto abort
    if % = 3 print $x+"Command not supported\n" goto abort
    print $x+"Mode set successfully\n"
:end_mode_set

# Establishing connection
    print $x+"Try to establish connection via APN "+$a+"\n"
    send "AT\^NDISDUP=1,1,\""+$a+"\"^m" 
    waitfor 5 "OK^m^j","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 1 print $x+"Error while connecting\n" goto abort
    if % = 2 gosub cme_error print $x+"Error "+$e+" while connecting\n" goto abort
    if % = 3 print $x+"Command not supported\n" goto abort
    print $x+"Waiting for establish connection\n"
    let r3 = 0
:wait_for_connection    
    let r3 = r3+1
    if r3 > 45 goto restart_modem
    if r3&3 = 3 print $x+"Still waiting ",r3-1," second(s)...\n"
    if r3 > 1 waitquiet 10 1
    send "AT\^DHCP?^m"
    waitfor 5 "\^DHCP:","ERROR^m^j","+CME ERROR: ","COMMAND NOT SUPPORT^m^j"
    if % = -1 goto comm_timeout
    if % = 0 print $x+"Connection established\n" goto conn_established
    if % = 1 goto wait_for_connection
    if % = 2 gosub cme_error goto wait_for_connection
    if % = 3 print $x+"Command not supported\n" goto abort
:conn_established
    waitfor 1 "OK^m^j"
    if % = -1 goto comm_timeout
    goto finish
    
# In case of normal exit
:finish
    print $x+"Done.\n"
    exit 0

# In case of occurred an error
:abort
    print $x+"Done!\n"
    exit 1

# Error CME routine
:cme_error
    get 1 "^m" $e
    let $e="'"+$e+"'"
    get 1 "^j" $t
    return

# Restarting modem and start all
:restart_modem
    let r1 = r1+1
    if r1 > 5 print $x+"Number of restart retries was exhausted\n" goto restart_final
    print $x+"Restarting modem\n"
    waitquiet 2 2
    send "AT\^NDISDUP=1,0^m"
    waitquiet 2 1
    send "ATZ0^m"
    waitquiet 2 1
    send "AT&F^m"
    waitquiet 2 1
    send "AT+CFUN=1^m"
    waitquiet 2 1
    let r3 = 0
:restart_wait    
    let r3 = r3+1
    sleep 1
    if r3&3 = 3 print $x+"Still waiting ",r3," second(s)...\n"
    if r3 < 20 goto restart_wait
    goto start
:restart_final
    waitquiet 2 1
    send "AT+CFUN=1,1^m"
    waitquiet 2 1
    goto abort
    
# Timeout detected
:comm_timeout
    print $x+"Modem is not responding, timeout detected\n"
    goto restart_modem
# Done